garethdn
garethdn

Reputation: 12351

Calling service method before manually bootstrapping Angular app

I have read through this question and answer but don't believe that it is the solution to my problem.

I have an app in which I require the currently logged-in user's details before loading up the app. This appears to be very similar to this question but the difference is that I want to use a method that already exists in my authenticationService before bootstrapping the app, and cache the result in that service.

app.bootstrap.js

(function(){
    'use strict';

    fetchUser()
        .then(bootstrapApplication);

    function fetchUser() {
        var injector = angular.injector(['app']);
        var authenticationService = injector.get('authenticationService');

        return authenticationService.getUser().then(function(response) {
          // Got user successfully, user is now cached in authenticationService.user
          console.log(response.data);
        });
    }

    function bootstrapApplication() {
        angular.element(document).ready(function() {
          angular.bootstrap(document, ['app']);
      });
    }

})();

I can call that service method fine, but the problem comes when I bootstrap the app and a new instance of that service is created and, as a result, the data I cached from the HTTP request is in a different instance of the service.

authentication.service.js

(function(){
    'use strict';

    angular
        .module('app.authentication')
        .factory('authenticationService', authenticationService);

    authenticationService.$inject = ['$http', '$cookies', '$log', '$q', 'API_SETTINGS', '_'];

    function authenticationService($http, $cookies, $log, $q, API_SETTINGS, _) {
        var factory = {
            user          : {},
            login         : login,
            logout        : logout,
            getUser       : getUser,
            isLoggedIn    : isLoggedIn,
            getSessionId  : getSessionId
        };

        return factory;

        function getUser() {
            return $http.get(API_SETTINGS.url + '/account', { 
                params: { 
                    'api_key'     : API_SETTINGS.key,
                    'session_id'  : $cookies.get('sessionId')
                }})
            .then(function(response) {
                // Great, cache the user and return the response
                factory.user = response.data;
                return response;
            });
        }

    }

})();

Is there anyway I can use the same instance of my authenticationService to make the HTTP call before bootstrapping and after? Or is there an alternative?

One thing I have considered is attaching the user to the window in the fetchUser success callback so that in my authenticationService I can set factory.user = $window.user || {}, but i'd prefer not to do it this way.

Upvotes: 3

Views: 1722

Answers (1)

Pavel Horal
Pavel Horal

Reputation: 18194

You can approach this from the other way around - let your Angular application bootstrap and just prevent your UI to do anything until the security service is initialized.

//~ ...

/**
 * Make UI Router wait.
 */
config(function($urlRouterProvider) {
    $urlRouterProvider.deferIntercept();
}).

/**
 * Initialize security and then activate UI Router.
 */
run(function($urlRouter, securityManager) {
    securityManager.init().then(function() {
        $urlRouter.sync();
        $urlRouter.listen();
    });
}).

//~ ...

Upvotes: 2

Related Questions