22

My style of writing angular controllers is like this (using controller name instead of function)

angular.module('mymodule', [
])
    .controller('myController', [
        '$scope',
        function($scope) {
            // Some code here

        }
    ]);

What I need now is when providing i routes I want to define resolve part:

 $routeProvider.when('/someroute', {
        templateUrl: 'partials/someroute.html', 
        resolve: myController.resolve}) // THIS IS THE CRITICAL LINE

Since controller is defined as a name how to accomplish resolve part bellow?

To clarify more in details I want to load some data from server before route is resolved and then use these data in controller.

UPDATE: To be more precise I want each module has its "resolve" function that will be called before root with that controller is executed. Solution in this post (answered by Misko Hevery) does exactly what I want but I don't have controllers as functions but as a names.

4 Answers 4

24

The controller definition and resolve parts are to be specified separately on the route definition.

If you define controllers on a module level you need to reference them as string, so:

 $routeProvider.when('/someroute', {
        templateUrl: 'partials/someroute.html', 
        controller: 'myController',
        resolve: {
          myVar: function(){
            //code to be executed before route change goes here
          };
        });

The above code also shows how to define a set of variables that will be resolved before route changes. When resolved those variables can be injected to a controller so taking the example from the snippet above you would write your controller like so:

.controller('myController', ['$scope', 'myVar', function($scope, myVar) {
            // myVar is already resolved and injected here
        }
    ]);

This video might help as well: http://www.youtube.com/watch?v=P6KITGRQujQ

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

10 Comments

@AndrejKaurin you can inject services to both your controller and resolve functions, if this is what you are asking... Could you be more precise?
Inside when(), should 'myController', be controller: 'myController',?
@MarkRajcok indeed. Fixed it.
@pkozlowski.opensource I get an error about myVarProvider is unknown. Any ideas why?
What version are you using?
|
13

@pkozlowski.opensource 's answer works, but I don't really want to mess up my routing and and controllers, because I always keep it separated (from Yo Generator). Actually, we can also have controller and resolve(r) all as string/name (NOT function).

angular.module('mymodule', [
])
  .controller('myController', [
      '$scope', 'myModelCombination'
      function($scope, myModelCombination) {
          // myModelCombination[0] === (resolved) myModel 
          // myModelCombination[1] === (resolved) myModel2

      }
  ])
  .controller('myController2', [
      '$scope', 'myModel'
      function($scope, myModel) {
          // Some code here

      }
  ])
  .factory('myModel', [
      '$scope',
      function($scope) {
          // return a promise

      }
  ])
  .factory('myModel2', [
      '$scope',
      function($scope) {
          // return a promise

      }
  ])
  .factory('myModelCombination', [
      '$scope', 'myModel', 'myModel2'
      function($scope) {
          return $q.all(['myModel', 'myModel2']);

      }
  ]);

Then in your routing file this should be added

$routeProvider.when('/someroute', {
    templateUrl: 'partials/someroute.html', 
    resolve: ['myModel'] //ALWAYS IN ARRAY)
});
$routeProvider.when('/myModelCombination', {
    templateUrl: 'partials/someroute2.html', 
    resolve: ['myModel'] //ALWAYS IN ARRAY)
});

http://docs.angularjs.org/api/ng.$routeProvider

3 Comments

myModel factory should return promise? Then how to return more promises via single factory (myModel in this case)? Or I should create new factory for every resolve.
Yes, each factory should return one and only one thing, either value or promise, unless you want to wait for everything and return all of it in $q.all(). Answer edited.
This doesn't seem to work. Can you a show a fiddle?
1

This would work too

var MyController = myApp.controller('MyController', ['$scope', 'myData', function($scope, myData) {
  // Some code here
}]);

MyController.resolve = {
  myData: ['$http', '$q', function($http, $q) {
    var defer = $q.defer();

    $http.get('/foo/bar')
      .success(function(data) {
        defer.resolve(data);
      })
      .error(function(error, status) {
        defer.reject(error);
      });

    return defer.promise;
  }]
};

Comments

0

@TruongSinh answer worked for me and is way nicer than having additional functions in the router. I tweaked it a little as it was returning the deferred object instead of the actual resolved data.

$routeProvider.when('/someroute', {
    templateUrl: 'partials/someroute.html', 
    controller: 'SomeController',
    resolve: {
       myModel: 'myModel'
    }
});

1 Comment

Would it be possible to post your entire solution here? I'm trying to do the same thing (returning a deferred object on resolve) and having difficulties to get it to work. Thanks.

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.