Skip to content

Conversation

@giovaniortolani
Copy link
Contributor

@giovaniortolani giovaniortolani commented Jun 24, 2025

Solution that covers most of the problematic scenarios described in #28.

Description of the problem and why it happens:

The ideal scenario would be the tag accessing the data model immediately when it runs, not from inside the injectScript success handler. However, access to the data model (window.dataTagGetData.dataModel) is only available after loading an external script because it's not possible to directly access some things in the global scope through GTM templates, hence the need for the external script.

However, GTM wraps the injectScript success/failure handlers in setTimeout(handler, 0), deferring their execution to the next event loop cycle. This delays data model access, making it too late to capture the correct state from the triggering data layer push.

Note: the Send all from DataLayer option collects the GTM dataModel, not the actual dataLayer object of when the tag fired (which can be different due to async operations). Learn more: [1] and [2].

Solutions:

  • A flag in window prevents injectScript() from running again after the script has loaded, avoiding repeated setTimeout executions. This flag is actually a flag for each script URL, to account for scenarios where multiple GTMs are executing the Data Tag (with or without the same script URL). [1]
  • The Event ID is saved in the tag’s global context before the injectScript handler runs, ensuring it's available to sendPostRequest(). This follows the same idea proposed here, but adjusts timing and placement. [1] [2]
  • Added a new currentEventObj property returned by dataTagData function in data-tag.js. It provides the actual event object that triggered the tag, useful when dataModel is not correct / not synced. [1] [2] [3]

Caveat:

  • If the tag fires multiple times before the script finishes loading, dataModel will reflect the state at load time, not trigger time. The currentEventObj property helps mitigate this.
  • The data returned and used from the dataModel will still be unsynced/wrong. Hence the currentEventObj.

@giovaniortolani giovaniortolani changed the title Race conditions issue fix Race conditions issue fix - Option 3 Nov 11, 2025
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

Successfully merging this pull request may close these issues.

3 participants