AngularJS - Resolve Conventions

The initial setup:

<div>
  <ng-view></ng-view>
</div>
var app = angular.module('app', []);

app.config(function ($routeProvider) {
  $routeProvider
    .when('/',
    {
      templateUrl: "app.html",
      controller: "AppCtrl"
      resolve: {
        app: function ($q, $timeout) {
          var defer = $q.defer;
          $timeout(function () {
            defer.resolve(); 
          }, 2000);
          return defer.promise;
        }
      }
    }
  )
});

app.controller("AppCtrl", function ($scope) {
  $scope.model = {
    message: "I'm a great app!"
  }
});
<h1>{{ model.message }}</h1>

Most of the time, resolve is associated with a controller - here, AppCtrl. This allows for promises to be decoupled from the router and declared separately, but still remain linked to its parent controller:

app.config(function ($routeProvider) {
  $routeProvider
    .when('/',
    {
      templateUrl: "app.html",
      controller: "AppCtrl"
      resolve: {
        loadData: appCtrl.loadData,
        prepData: appCtrl.prepData
      }
    }
  )
});

var appCtrl = app.controller("AppCtrl", function ($scope) {
  $scope.model = {
    message: "I'm a great app!"
  }
});

appCtrl.loadData = function ($q, $timeout) {
  var defer = $q.defer;
  $timeout(function () {
    defer.resolve(); 
  }, 2000);
  return defer.promise;
};

appCtrl.prepData = function ($q, $timeout) {
  var defer = $q.defer;
  $timeout(function () {
    defer.resolve(); 
  }, 2000);
  return defer.promise;
};

Here, the promises are enqueued and resolved in the same fashion, only with a much neater syntax.

Adding console.log to each gives a clearer idea of what’s going on under the hood:

appCtrl.loadData = function ($q, $timeout) {
  var defer = $q.defer;
  $timeout(function () {
    defer.resolve(); 
    console.log("loadData");
  }, 2000);
  return defer.promise;
};

appCtrl.prepData = function ($q, $timeout) {
  var defer = $q.defer;
  $timeout(function () {
    defer.resolve(); 
    console.log("prepData");
  }, 2000);
  return defer.promise;
};

Running this shows that the promises don’t actually happen sequentially. Once both of them are ready, that will trigger the route change.

var appCtrl = app.controller("AppCtrl", function ($scope, $route) {
  $console.log($route);
  $scope.model = {
    message: "I'm a great app!"
  }
});

appCtrl.loadData = function ($q, $timeout) {
  var defer = $q.defer;
  $timeout(function () {
    defer.resolve("loadData"); 
  }, 2000);
  return defer.promise;
};

appCtrl.prepData = function ($q, $timeout) {
  var defer = $q.defer;
  $timeout(function () {
    defer.resolve("prepData"); 
  }, 2000);
  return defer.promise;
};

By passing strings to the resolve method and inspecting the route in the console, $route.current.locals will have the loadData and prepData attributes, with their respective string values that were returned from the promise.