2

I am eagerly trying to create a dyanmic $StateProvider:

Standard static $StateProvider:

    $stateProvider
      .state('main',
      {
        url: '/',
        templateUrl: '/views/main.html',
        controller: 'MainCtrl'
      })
      .state('login',
      {
        templateUrl: '/views/login-form.html',
        controller: 'LoginCtrl'
      })
      .state('logout',
      {
        controller: 'LogoutCtrl'
      })
      .state('sales', {
        templateUrl: '/views/sales-data.html',
        controller: 'SalesDataCtrl',
        resolve: {
          user: 'User',
          authenticationRequired: function(user) {
            user.isAuthenticated();
          }
        }
      });

Dynamic $StateProvider:

var verify = function(user) { user.isAuthenticated(); };

var states= [
{ name: 'main', url: '/', templateUrl: '/views/main.html', controller: 'MainCtrl' },
{ name: 'login', url: '', templateUrl: '/views/login-form.html', controller: 'LoginCtrl' },
{ name: 'logout', url: '', templateUrl: '', controller: 'LogoutCtrl' },
    {
        name: 'sales',
        url: '',
        templateUrl: '/views/sales-data.html',
        controller: 'SalesDataCtrl',
        //resolve:
        //[
        //    { user: 'User', authenticationRequired: 'verify();' }
        //]
    }
];
       // w/o the array brackets in resolve the navigation does not work.
       // with the array brackets, once sales is clicked I get:
       // Error: [ng:areq] Argument 'fn' is not a function, got Object

The two methods below work as long as I am not using resolve:

  This works:
   angular.forEach(states, function(state) {
        $stateProvider.state(state);
    });

   This works:
   angular.forEach(states, function(state) {
        $stateProvider.state(state.name, state);
    });

Question: How can I make this dynamic $StateProvider work with the resolve?

2 Answers2

2

Solution:

var states = [
{ name: 'main', url: '/', templateUrl: '/views/main.html', controller: 'MainCtrl' },
{ name: 'login', url: '', templateUrl: '/views/login-form.html', controller: 'LoginCtrl' },
{ name: 'logout', url: '', templateUrl: '', controller: 'LogoutCtrl' },
    {
        name: 'sales',
        url: '',
        templateUrl: '/views/sales-data.html',
        controller: 'SalesDataCtrl',
        resolve: {
            user: 'User',
            authenticationRequired:
            ['user', function(user) { user.isAuthenticated(); }] // <-------------------------
        }
    }
];

    angular.forEach(states, function (state) {
        $stateProvider.state(state.name, state);
    });
  • I have a very similar problem, except I'm using views with resolve and I can't seem to get it working. So far your solution is by far the closest I could find, any help with my issue here is greatly appreciated! - http://stackoverflow.com/questions/26630586/angularjs-dynamic-stateprovider-with-ui-router-views-and-oclazyload-resolves – Frankie Loscavio Oct 29 '14 at 12:42
0

I think you're calling $stateProvider.state(...) incorrectly, it takes a state ID and then the configuration object.

Assuming your name properties are valid and unique you should just be able to do this (or adjust it as needed):

angular.forEach(states, function(state) {
    $stateProvider.state(state.name, state);
});
Sly_cardinal
  • 12,270
  • 5
  • 49
  • 50
  • The way I did it above worked fine, and your way worked fine as well, however, even with your way I cannot use resolve. –  Jun 03 '14 at 00:29
  • Ok, fair enough. In what way is the resolve not working? Are you expecting the navigation to wait for the `authenticationRequired()` method? – Sly_cardinal Jun 03 '14 at 00:31
  • If you read above I mention what happens: Either nav to sales does not work or (b) Error: [ng:areq] Argument 'fn' is not a function, got Object –  Jun 03 '14 at 00:40
  • OK, if the `resolve` property is an object then it will pass that through as the resolved data to the stateChangeSuccess handler, if it's an array then it's trying to interpret it as Inline Array Annotation and it needs a function definiton inside the array (https://docs.angularjs.org/guide/di#inline-array-annotation). Are you wanting the navigation to wait for the authenticationRequired() method, or something else? – Sly_cardinal Jun 03 '14 at 01:13