Skip to content

Instantly share code, notes, and snippets.

@khoand0000
Last active December 6, 2015 19:01
Show Gist options
  • Save khoand0000/0f92108c076e1f02a82b to your computer and use it in GitHub Desktop.
Save khoand0000/0f92108c076e1f02a82b to your computer and use it in GitHub Desktop.
Using resolve with $stateProvider. Ref: https://github.com/angular-ui/ui-router/wiki

My situation is that: I write a web-app like gmail: normal messages, starred messages, label messages sections (3 states). They have same functions except different webservice calling. But format of their result are same:

{
  "result": [],
  "count": 5
}

I want to use only controller for 3 states. So I use resolve to achieve that.

  • Solution 1:
// route.js
/*
Message.listMessages() and Message.listStarredMessages() are custom `actions` of $resource. Message is factory
*/

$stateProvider
  .state('dashboard.messages', {
      // ...
      controller: 'SharedMessagesController',
      controllerAs: 'vm',
      resolve: {
        obj: function (Message, $stateParams) {
            return Message.listMessages({
                    page: $stateParams.page
                });
      }
  })
  .state('dashboard.starred-messages', {
    // ...
    controller: 'SharedMessagesController',
    controllerAs: 'vm',
    resolve: {
      obj: function (Message, $stateParams) {
          return Message.listStarredMessages({
                  page: $stateParams.page
              });
    }
  });
// shared-messages.controller.js
angular
    .module('app.message')
    .controller('SharedMessagesController', SharedMessagesController);

SharedMessagesController.$inject = ['obj'];

/* @ngInject */
function SharedMessagesController(obj) {
    var vm = this;
    vm.messages = obj; // when obj is resolved, messages will have result
}
<!-- messages.html -->
<div ng-repeat="message in vm.messages['result']">
<!-- do something -->
</div>
  • Solution 2: Perfect! But I want to using <div ng-repeat="message in vm.messages"> instead of <div ng-repeat="message in vm.messages['result']">. I need to change shared-messages.controller.js file
// shared-messages.controller.js

/* @ngInject */
function SharedMessagesController(obj) {
    var vm = this;
    vm.messages = [];
    
    // after server return result, will assign it to `vm.messages`
    obj.$promise.then(function(data) {
      vm.messages = data['result'];
    });
}
  • Solution 3: The solution is good. But there is one more way to achieve same result.
// route.js
  .state('dashboard.messages', {
      // ...
      controller: 'SharedMessagesController',
      controllerAs: 'vm',
      resolve: {
        obj: function (Message, $stateParams) {
            return Message.listMessages({
                    page: $stateParams.page
                }).$promise; // controller will waiting until server return result (is resolved)
      }
  })
// shared-messages.controller.js

/* @ngInject */
function SharedMessagesController(obj) {
    var vm = this;
    vm.messages = obj['result']; // obj now is ready to use, don't need to waiting like 2 above solutions
}
  • I like solution 2 because controller doesn't need to waiting, and template works to variable directly instead of that children property of the variable

Ref: https://github.com/angular-ui/ui-router/wiki

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment