5

I have an ajax call inside the .run() that loads a variable into the $rootScope That variable is needed in the controller associated with a view.

Sometimes on refresh (F5) by the time the .controller is loading there is nothing inside $rootScope.user.fedUnit resulting in:

TypeError: Cannot read property 'fedUnit' of undefined

Any way to delay loading the controller until after the .run() is finished? Can't seem to find it.

app.run(function($rootScope, $http, $location, SessionFactory, TokenHandler) {
    token = TokenHandler.getToken();
    if ( token != null ) {
        SessionFactory.get( { token : token },
            function success(response, responseHeaders) {
                $rootScope.user = response;
            }
        );
    }
});

app.controller('UnitController', function($scope, $rootScope, $location, UnitFactory) {
    $scope.updateUnits = function () {
        UnitFactory.query({fedUnit: $rootScope.user.fedUnit}, function success(response, responseHeaders) { ...

Solution

$rootScope.foo = $q.defer();
$rootScope.foo.resolve(); when AJAX is done;
$rootScope.foo.promise.then(..) in the controller.

thanks to @misterhiller (twitter)

4
  • 3
    I feel that your run() has actually finished before the controller loads - its just that the run() seems to contain an asynchronous call - It is called and forgotten until it returns, while the browser proceeds with the execution of the next set of code - in the process calling your controller - since the GET request still would not have returned (in that split second) and thus results in the error - Could you post the code for the SessionFactory service? Commented Jun 6, 2013 at 14:23
  • You need to make this work asynchronously. Create a provider which loads performs the AJAX request. Commented Jun 6, 2013 at 14:28
  • Yes, The Sessionfactory is a simple $resource call to some sort of rest API. Commented Jun 6, 2013 at 17:27
  • Thanks for the solution. That safed my day. So i added a functional code sample. Commented Aug 21, 2013 at 17:32

1 Answer 1

7

The solution at functional code block:

app.run(function($rootScope, $http, $q, SessionFactory, TokenHandler) {

    $rootScope.ajaxCall = $q.defer();

    token = TokenHandler.getToken();
    if ( token != null ) {
        SessionFactory.get( { token : token },
            function success(response, responseHeaders) {
                $rootScope.user = response;

                $rootScope.ajaxCall.resolve();
            }
        );
    }
});

app.controller('UnitController', function($scope, UnitFactory) {

    $scope.ajaxCall.promise.then(function() {
        $scope.updateUnits = function () {
            UnitFactory.query({fedUnit: $scope.user.fedUnit});
        }
    });
});

I don't use $rootScope in the controller.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.