nagyf nagyf - 2 months ago 17
AngularJS Question

Angular ui-router resolve inheritance

I would like to create an abstract parent state, that has only one job: to resolve the current user through an ajax server call, and then pass this object to the child state. The problem is that the child state never gets loaded. Please have a look at this plunker: Example

a

state


angular.module('test', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider){

// Parent route
$stateProvider.state('main', {
abstract:true,
resolve: {
user: function(UserService){
return UserService.getUser();
}
}
});

// Child route
$stateProvider.state('home', {
parent: 'main',
url: '/',
controller: 'HomeController',
controllerAs: '$ctrl',
template: '<h1>{{$ctrl.user.name}}</h1>'
});

$urlRouterProvider.otherwise('/');
});


a
factory


angular.module('test').factory('UserService', function($q){
function getUser() {
var deferred = $q.defer();

// Immediately resolve it
deferred.resolve({
name: 'Anonymous'
});

return deferred.promise;
}

return {
getUser: getUser
};
});


a
controller


angular.module('test').controller('HomeController', function(user){
this.user = user;
});


In this example, the
home
state will never display the template, I don't really understand why. If I remove the
parent: 'main'
line, then it displays the template, but of course I get an error because it cannot find the
user
dependency in the
HomeController
.

What am I missing? I did everything like it is described in ui-router's documentation, I think this should work.

Answer

Every parent must have a target ui-view in template for its child

$stateProvider.state('main', {
  abstract:true,
  resolve: {
    user: function(UserService){
      return UserService.getUser();
    }
  }
  template: '<div ui-view=""></div>'
});

NOTE: Another option is to use absolute names and target index.html .. but in this case the above is the way to go (Angularjs ui-router not reaching child controller)