7

My AngularJS resolve doesn't finish before the controller is loaded.

Background: Say I have a "my profile" page that is requested (user loads website.com/user). I would like to have angular intercept the request and ask for the appropriate data from the server.

The server will reply differently depending on whether the user is logged in/active/etc. I would like angular to get the data from the server before it loads the template, and before it initiates the appropriate controller. So far it does not.

App.js code:

.when('/user',
  {
    templateUrl:'/templates/user',
    controller: 'my_profile',
    resolve: {
        some_cute_function_name: function($timeout){
            $timeout(function(){
                console.log('here123');
            },5)
        }
   }

Meanwhile, controller code:

            console.log('about to update scope');

It turns out that the controller is initiated before the resolve is done. I know this because the greater the number of seconds before the $timeout is done, the more likely I am to see this:

about to update scope
here123

as opposed to the other way around.

Is there any way to ensure that the resolve is resolved before the controller is initiated?

Much appreciated!

5
  • Why cant you call some_cute_function_name from within the controller? Commented Dec 23, 2013 at 1:47
  • I can, but I wanted to make sure that the data is retrieved before the view is rendered. The resolve function shown here is a simplified version of an AJAX call I'm performing. Commented Dec 23, 2013 at 1:51
  • There is return statement missing in some_cute_function Commented Dec 23, 2013 at 1:52
  • That's right @Chandermani, I've tried that. But even if I add it (either after '},5)' or after '},5)}' - it still doesn't work =(. Wait, do I have to return something relevant, or should "return 3" work? Commented Dec 23, 2013 at 1:56
  • The return would be return $timeout(.... Commented Dec 23, 2013 at 2:13

2 Answers 2

5

Your resolver needs to return a promise:

  .when('/user',
  {
    templateUrl:'/templates/user',
    controller: 'my_profile',
    resolve: {
        some_cute_function_name: function($timeout){
            return $timeout(function(){
                console.log('here123');
                return { some: 'data' };
            },5);
        }
   }
Sign up to request clarification or add additional context in comments.

2 Comments

You don't need to create a new deferred object. $timeout itself returns a promise.
Updated to just return the $timeout's promise.
0

AngularJS describes resolve as:

"An optional map of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected before the controller is instantiated." (emphasis added)

I take it that unless any of the dependencies are promises, angular won't wait for resolve to finish before instantiating the controller (even if I have operations that take a long time to finish, like a $timeout).

Solution: you have to make sure the resolve involves a promise.

3 Comments

Hi Adam, I am also facing the same issue, inside my resolve I am calling a factory function in which I am making an http request and inside .then(function(response){.....) I am performing some actions and returning the desired data, do you know what is wrong here? MY_CODE: resolve: some_cute_function_name: function(factory){ return factory.function(params);} IN_FACTORY : I am returning the data inside .then of http
@SohailFaruqui are you sure that the factory function is returning a promise?
I think I forgot to return promiss

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.