My name is Carl. I am a software engineer and architect. I blog about C#, .NET, Javascript, AngularJS, nodejs, and more. Thanks for visiting!



Buy me a coffeeBuy me a coffee

Tags

AngularJS Route Resolve Example

The resolve property is attached to a route in AngularJS to provide a list of dependencies for the route. The data from this list is injected into the route controller and if any of the dependencies are promises, the promise will be resolved before the controller is instantiated. This helps keep the controller clean because any data the controller depends on can be injected into it instead of the controller retrieving that data itself. This post will go through an example of using the resolve property and show the differences between using a resolve property versus putting the fetch code in the controller directly. The full example can be found in this plunk. It's a little confusing just looking at code snippets so I suggest opening the example in another window and following along.

I'm going to start with an example of using the controller directly. There is a simple template that displays a greeting. This is in greetingTemplate.html.


<p>Greeting Below</p>
<p>{{answer}}</p>


Next, there is a greeting service that returns a promise with a greeting. The result is wrapped in a $timeout call to simulate a long running process, such as retreiving data from an API.

app.service('greetingService', function($q, $timeout) {
     var _this = this;
     _this.getGreeting = function() {
          return $q(function(resolve, reject) {
               $timeout(function() {
                    console.log("Inside promise");
                    resolve("Hello from the greetings service");
               },5000);
          });
     };
});


The controller fetches the greeting from the greeting service and sets the answer property that is shown in the template. It's called when the controller is instantiated. This section of the controller can get quite large if it needs several pieces of data.

app.controller('greetingCtrl', function($scope, greetingService) {
    // Call service from beginning of controller directly. Route is resolved without waiting for this
    var greetingPromise = greetingService.getGreeting();
    greetingPromise.then(function(greeting) {
        console.log(greeting);
        $scope.answer = "Successful Greeting = "+greeting;
      }, function(failure) {
          $scope.answer = failure;
          console.log("UI failure message");
        });
});


Finally, the route that puts it all together.

$routeProvider.when('/', {
        templateUrl: 'greetingTemplate.html',
        controller: 'greetingCtrl'
    });



Next I'll show an example of replacing the code in the controller with the resolve property on the route. If you're following along in the example, comment out the top half of script.js and uncomment the bottom half. This has the updated route using the resolve property.

The modified route is below. Notice the resolve property is an object that has a property of it's own called 'greeting'. The greeting property is a function that takes the greetingService as a dependency and returns a call to getGreeting(). That's a mouthful but basically we're taking the greetingService dependency and moving it from the controller to the route. In this case the 'greetingCtrl' controller will not be instantiated until the call to greetingService.getGreeting() is resolved.

$routeProvider.when('/', {
      templateUrl: 'greetingTemplate.html',
      controller: 'greetingCtrl',
      // When the resolve property is used in the route, the route will wait to return until all properties of the object are resolved
      resolve: {
        greeting: function(greetingService){
            return greetingService.getGreeting();
        }
      }
    });


Lastly, this is the updated controller. It takes a paramter called greeting. This matches the name of the resolve property on the route above and contains the data returned by the greetingService.getGreeting() promise. It is important to note that even though getGreeting returns a promise, the value of the greeting parameter in the controller is "Hello from the greetings service". This is the value of the resolved promise. Because of this, the controller can simply use the data that is passed in.

app.controller('greetingCtrl', function($scope, greeting) {
     $scope.answer = greeting;
});



There is one point I should address before wrapping up. If there are long running operations being performed by the resolve properties, it could take a while before the page is rendered since all properties are resolved before the controller is instantiated. If time to first page draw is most important this method probably isn't for you and you will probably prefer handling dependencies in the controller and using a loading widget in the templates to specify which dependencies are still loading. This can be seen in the example. It takes 5 seconds for the service to resolve the promise so the second version of the route will take 5 seconds before anything is rendered to the page. The first line of the template renders immediately in the version of the route that doesn't use resolve.

In conclusion, the resolve property of a route can organize controller dependencies on the route object directly and make controller code smaller. Multiple properties can be passed into resolve if the controller has multiple dependencies. Services can be injected into functions used by the resolve property as well so the heavy lifting can still be done in services. The remaining question I have for all of this is what happens when a promise fails? Does the route load? I'll look at this in my next post.




If you enjoyed this article...

Buy me a coffeeBuy me a coffee



© 2025 Carl Layton Creative Commons License Disclaimer
An unhandled error has occurred. Reload 🗙