I’m having issues with waiting for the data needed within the DataLayer to become available for use later. At the moment I’ve got a setTimeout delay will help “solve” the problem but it’s obviously not a long-term solution since the DataLayer could take longer than my Timeout and I’d get the wrong data.
I’m working with an SPA which means I need to re-run my code when the page changes, and call the DataLayer again to then filter the data.
What I want to do is:
Call DataLayer on each page change
Filter through the data returned to find all instances of “view_item”
Look for the last “view_item” and print this out (for now - I’ll add further processing later)
setTimeout(function () {
console.log("Initial dataLayer: " + JSON.stringify(dataLayer));
// Update view_item with the latest dataLayer
let view_item = dataLayer.filter(o => o.event === "view_item"); // Initialize view_item with initial dataLayer state
// Log the length of the view_item array after filtering
console.log("Length of view_item: " + view_item.length);
// Log the items in view_item
logItems(view_item);
}, 5000);
function logItems(item) {
if (item) { // Check if item is defined
item.forEach(item => {
console.log("item: " + JSON.stringify(item));
});
} else {
console.log("view_item is null or undefined.");
}
}
Hi @Shoxt3r, I don’t think the data layer is supposed to be read at all, it’s meant for pushing and can populate itself later with the usual
window.dataLayer = window.dataLayer || []
… but there’s no explicit way to wait for it AFAIK.
So if you need to know if a certain event has already been pushed, I’d suggest to create your own dedicated storage for this (e.g. in the session storage) and then push your events to both.
Sorry - it comes through from window.dataLayer which is used by Google Tag Manager. It’s an object which has a range of events fed into it which I’m trying to pull together and then loop through to get the information needed. I don’t work on the backend of the website as that’s handled by a third-party so I’m unsure.
Thanks I’ll have a look into session storage. Basically, a number of events get pushed into the dataLayer as the user navigates around the website. I’m attempting to pick up on the “view_item” event, so I would imagine I’d want to check for any updates on the dataLayer with each new page view and then pick up on the “view_item” events to get the information I need. However, from what I’ve done so far, the call to dataLayer is happening too quickly and it only gets part of the data.
However, if there’s a better way of picking up on that same information then please let me know.
And yes, that’s correct - it’s coming through from Google Tag Manager.
Well if the event isn’t getting pushed from your own application code, can you find out what exactly triggers the event and then basically track it yourself?
Or do you need to know what’s in the data layer specifically? Then maybe something like this (pursuing @rpg_digital’s idea)…
let dataLayer
Object.defineProperty(window, 'dataLayer', {
get () {
return dataLayer
},
set (value) {
dataLayer = value
// Do something
console.log('data layer set')
}
})
Edit: Okay this won’t get triggered when pushing new events. See below for a more sophisticated solution. :-)
Thanks a lot! I’ll give that a go. Presumably this could be setup to pick up on the dataLayer which is effectively an “external” array source? As I say data gets pushed in from the website remotely and I don’t have any control over when these pushes happen.