Race conditions issue fix - Option 1 #41
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR totally solves the issues #28 and https://community.stape.io/t/data-tag-client-property-pollution-across-events/3425/15, and is an alternative and better option to the PR #33.
Solution that covers all problematic scenarios described in #28 and https://community.stape.io/t/data-tag-client-property-pollution-across-events/3425/15.
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
injectScriptsuccess 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.However, GTM wraps the
injectScriptsuccess/failure handlers insetTimeout(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 DataLayeroption 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:
windowpreventsinjectScript()from running again after the script has loaded, avoiding repeatedsetTimeoutexecutions. 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]dataTagGetDataglobal function fromdata-tag.jsnow accepts 3 new arguments:Event ID, a flagUse Own Data Modeland a flagUse only current data layer event object. TheUse Own Data Modelflag, when enabled, recreates thedataModelmanually by replicating what GTM does under the hood, and it doesn't use the nativedataModelvalue from GTM (as suggested here). And theUse only current data layer event object, if enabled, only uses the data layer event that triggered the tag.[1] [2] [3].
injectScripthandler runs, ensuring it's available tosendPostRequest(), and is passed to thedataTagGetDataglobal function fromdata-tag.jsto be used to locate the actual data layer event that triggered the tag, and then build thedataModelmanually. This follows the same idea proposed here, but adjusts timing and placement. [1] [2]