How do I ensure utag.js is loaded from within client side framework like angular

Silver Contributor
Silver Contributor
I am currently loading the utag.js asynchronously. This becomes a problem for me in a single page angular app because viewContentLoaded does not know when the utag variable is available. I am using utag.view to track "page" changes into GA. However, a race condition exists where utag.js finishing loading after my angular app loads. The only solution to this I can think of is set a timeout for 50ms and keep checking when utag is not undefined. Are there any better ways of handling this situation?
7 REPLIES 7

How do I ensure utag.js is loaded from within client side framework like angular

Employee Emeritus
Another possible solution is to add a Javascript Code extension in your Tealium configuration to fire a custom event. There are two possible scopes that you could use: * Preloader scope: this runs as soon as the utag.js file loads, but before the utag object is fully initialised. * DOM Ready: this runs after the utag object is initialised, and before the tags all fire. At this point the utag object will exist and the utag_data object will be populated. Unlike the All Tags scope, it only runs once, it does not get executed each time a view event fires. I would suggest experimenting with firing the Angular callback / event from code in the DOM Ready scope. Please let us know how you get on, if it works well then it could be a good candidate for a new standard feature!

How do I ensure utag.js is loaded from within client side framework like angular

Silver Contributor
Silver Contributor
I will give that a try. I would say it's not exactly an ideal solution though. That really makes it difficult for a developer to follow what is going on. I would have preferred a dedicated asynch solution similar to how GA handles pushing variables regardless of whether _gaq object is available. This requires me to hide an event firing directly in tealium. When you have a large site, these kinds of details can get lost.

How do I ensure utag.js is loaded from within client side framework like angular

Employee Emeritus
Chris, In my sample project for a simple angularJS module there is some sample code and a small readme. https://github.com/patrickmcwilliams/angularJS_tealiumIQ-module If you define a variable that wraps a utag.view() in your app controller and then use it in an "onload" on an ng-include or ng-view. Alternatively, you can call the wrapper after a $routeChangeSuccess callback. If all of this is still happening too soon because you have some other modules that are loading information asynchronously, then you may need to create a global object that keeps track of what modules should load for any given view and then at the completion of each module mark the global object as complete. Doing one final check for if all modules have completed and then calling utag.view() only after then. example: window.modules_loaded = { mod1: false, mod2:false, mod3:false } at the completion of modx: ... modules_loaded.modx=true; var run_tealium = false; for (var val in modules_loaded) { run_tealium = val; } if (run_tealium){ utag.view({DATA}); } Let me know if any of this helps, or if the info in git is helpful.

How do I ensure utag.js is loaded from within client side framework like angular

Silver Contributor
Silver Contributor
"If you define a variable that wraps a utag.view() in your app controller and then use it in an "onload" on an ng-include or ng-view." This is what we're doing. We're doing $viewContentLoaded and trying to access utag. That's the crux of the problem is that on the first load of the app, utag is not yet initialized. Basically the issue is on the first load of a single page app. Every route change thereafter is fine since utag is already loaded

How do I ensure utag.js is loaded from within client side framework like angular

Employee Emeritus
When utag.js loads for its very first time, it will call a utag.view() itself without the page having to explicitly call it, unless you have defined an object prior to its load like: var utag_cfg_ovrd={noview:true} If this object is defined prior to loading utag.js thenyou will have to call a utag.view() on the first page of an ajax web app. My question is, is it possibly to suppress the very first utag.view() that you are calling on $viewContentLoaded? Otherwise, even if you resolve the race condition you will be tracking your first view twice. You have two options. 1) Resolve the race condition and add 'var utag_cfg_ovrd={noview:true}' before loading utag.js 2) Suppress utag.view() being called on the initial view of the app. You can set a flag like 'first_view = true' and then wrap your utag.view() call with a conditional. $rootScope.$on("$viewContentLoaded", function (event, viewConfig) { if (!first_view){ tealium.view(); } else { first_view = false; } }); This way you can let utag.js call its own utag.view when the library is ready and allow $viewContentLoaded to call utag.view() on every subsequent view change. Let me know if this might be a viable solution.

How do I ensure utag.js is loaded from within client side framework like angular

Silver Contributor
Silver Contributor
#2 doesn't quite work because view() would be called with the direct URL. We're giving it a custom value since the URL has a # in it. So I suppose #1 would be the only option, which still puts us as solving the race condition

How do I ensure utag.js is loaded from within client side framework like angular

Employee Emeritus
I still think #2 is the proper solution, lets set up a call so we can figure this out for you. I have reached out to your Account Manager and we will be contacting you with your first available time to work on this. You can also try and reach me on skype: raysireks for some quick QA. But we will move forward with the call ASAP.
Public