Race conditions issue fix - Option 3 #33
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.
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
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, hence the need for the external script.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]injectScripthandler runs, ensuring it's available tosendPostRequest(). This follows the same idea proposed here, but adjusts timing and placement. [1] [2]currentEventObjproperty returned bydataTagDatafunction indata-tag.js. It provides the actual event object that triggered the tag, useful whendataModelis not correct / not synced. [1] [2] [3]Caveat:
dataModelwill reflect the state at load time, not trigger time. ThecurrentEventObjproperty helps mitigate this.dataModelwill still be unsynced/wrong. Hence thecurrentEventObj.