Search code examples
javascriptangularjsrootscopedependency-resolver

access $rootScope in resolve and root index.html file


Two things -

I have a vendor script in the head of my index.html to which I would like to pass an environment specific variable.

<script type="text/javascript">!function () {analytics.load(--->code here<----);();</script>

I have attached the variable to the $rootScope in the run block, but it does not appear to be ready when this html is loaded. I am able to log the same code with

<a data-ng-click="$log.log('code', code)">code</a>

but it does not appear to be ready when the head tag is run.

Also - I have some other values I have attached to $rootScope that are not available when the resolve runs. It is undefined in the service. If I do a console.log in that service and a console.log in the run block, the service logs first as undefined, and then when the run block is executed, it has been set correctly.

What do I need to do to use these variables in the head element of the root index.html file, and in the resolve?

resolve: {
    auth: ['service', function (service) {
        return service.resolve()
    }]
}

service.resolve calls a number of different services for variable dependencies required before the page renders.

Update

The resolve I mentioned before is a $route.resolve function. It is placed in the routeProvider and run before the page loads.

templateUrl: '/user.html',                    
controller: 'User',
controllerAs: 'user',
resolve: {
    auth: ['service', function (service) {
        return service.resolve()
    }]
}

resolve function contents -

self.profilePromises().then(function (resp) {
    //this resp object is an array of promises that are mostly put into rootscope and/or used as params for other app setup functions - all things that need to be ready before the page resolves

    var map = self.resultMap

    for (var i = 0; i < resp.length; i++) {

        $rootScope[map[i]] = resp[i].data.data

        switch (map[i]) {
            case 'abc':
                $rootScope.abc = resp[i].data
                break
            case 'def':
                setUser(resp[i].data.data)
                break
            // etc
        }
    }
    return $q.when({auth: true})

}, function (resp) {
    return $q.reject({auth: false})
})

$route.resolve can take multiple function arguments that must execute before the page is initialized. This is the best way I have found for acquiring variables necessary to load the page. Therefore they are often services that fetch user data that is used to populate the page, after login for example. These variables I'm trying to attach to rootScope are coming from our build, which will pass host & port params relative to production or QA. In other words, I want to assign these domains when the app is built depending on environment.


Solution

  • I have attached the variable to the $rootScope in the run block, but it does not appear to be ready when this html is loaded.

    $rootScope is available when angular goes through bootstrapping process and creates $injector. The boostrapping process can be initiated through ng-app directive or angular.bootstrap method. In any case, these have to be called when DOM is ready, because angular can't bootstrap without DOM element. All scripts in head block are executed before the DOM is ready and so there is no way you can access $rootScope at that point.