Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible race condition when dataTagGetData from 2 rapidly fired data layer events #28

Open
hugentobler opened this issue Dec 20, 2024 · 3 comments

Comments

@hugentobler
Copy link

At the moment, when marking "add_data_layer" to true on the Data Tag, the following function is called in browser window to retrieve the latest dataLayer data. However, if one has 2 of the same event firing in rapid succession in the client, the Data Tag is always only able to grab the latest dataLayer data of the second event. Resulting in a race condition. Any suggestions on how to solve this? For now I must unpack the dataLayer data on the client-side and send it as an event or user property.

function dataTagGetData(containerId) {
    window.dataTagData = {
        document: {
            characterSet: window.document.characterSet,
        },
        innerWidth: window.innerWidth,
        innerHeight: window.innerHeight,
        screen: {
            width: window.screen.width,
            height: window.screen.height,
        },
        dataModel: window.google_tag_manager[containerId].dataLayer.get({
            split: function() { return []; }
        }),
    };

    return window.dataTagData;
}
@Bukashk0zzz
Copy link
Member

Hi, Thanks for the issue.

I think a workaround for this should be in gtm.uniqueEventId.
Theoretically, you can use let gtmId = copyFromDataLayer('gtm.uniqueEventId') || 0;
and pass it to this function and receive a specified dataLayer push.

But this needs to be tested.

I added this bug to our backlog.
But we will be happy if you send us a PR with the fix.

@hugentobler
Copy link
Author

Hi thanks, this is what I attempted and tested, but then I realised that it seems the only way to get the uniqueEventId is by using copyFromDataLayer, which still suffers from the race condition. Any ideas?

template.js

function addCommonDataForPostRequest(data, eventData) {
  const eventId = copyFromDataLayer('gtm.uniqueEventId');
  if (data.add_common || data.add_data_layer) {
    const dataTagData = callInWindow(
      'dataTagGetData',
      getContainerVersion()['containerId'],
      eventId
    );

    if (data.add_data_layer && dataTagData.dataModel) {
      if (dataTagData.eventMatched) {
        for (let dataKey in dataTagData.dataModel) {
          eventData[dataKey] = dataTagData.dataModel[dataKey];
        }
      }
    }

    ...

data-tag.js

function dataTagGetData(containerId, eventId) {
  var dataLayer = window.google_tag_manager[containerId].dataLayer;

  var dataModel = eventId
    ? dataLayer.get(eventId)
    : dataLayer.get({
      split: function() { return []; }
  });

  window.dataTagData = {
      document: {
          characterSet: window.document.characterSet,
      },
      innerWidth: window.innerWidth,
      innerHeight: window.innerHeight,
      screen: {
          width: window.screen.width,
          height: window.screen.height,
      },
      dataModel: dataModel,
      eventMatched: !!dataModel  // false if the event ID was not found
  };

  return window.dataTagData;
}

@Bukashk0zzz
Copy link
Member

Sorry for now, no better ideas.
But we will discuss this issue internally with the team when we come to it.

Thanks for your input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants