You've probably already seen it:
var datalayer = [];
datalayer.push({
event: 'test'
});
// later we load the gtm script and it processes the infos
// and when we call push again it processes it immediately.
datalayer.push({
event: 'second'
});
datalayer is an Array. The trick is just to redefine the push method.
function pushModule(root, name, callback) {
// new push method
function push(data) {
root[name]._push.apply(root[name], arguments);
callback(data);
}
// if not defined before
root[name] = root[name] || [];
// save native push method
root[name]._push = root[name].push;
root[name].push = push;
console.log(root[name].push);
for (var i = 0; i < root[name].length; i++) {
callback(root[name][i]);
}
}
// usage
pushModule(window, 'datalayer', handlerFunction);
In this code excerpt, we first define our new push function then we save the native one to replace it with our version.
Then we process all the existing entries in the table.
This pattern has the great advantage of enabling the provisionning of events, behavior or data on a page without having the consumer ready at the moment of publication.
The script consuming the array can then be loaded async/defer or just at the bottom of the page.
We use this in our development to 1) build list of components that needs js behaviors "upgrades" and 2) to expose "events" for the analytics, and this while still being able to defer the load of the scripts in charge.