0

I have a few states and i can successfully load all the states using url and template url like following

app.config(function ($stateProvider, $urlRouterProvider) {

$urlRouterProvider.otherwise('app/dashboard-v1');
$stateProvider.state('app', {
    abstract: true,
    url: '/app',
    templateUrl: 'tpl/app.html'
}).state('app.dashboard-v1', {
    url: '/dashboard-v1',
    templateUrl: 'tpl/app_dashboard_v1.html',
    resolve: {
        deps: ['$ocLazyLoad',
            function ($ocLazyLoad) {
                return $ocLazyLoad.load(['controllers/chart.js']);
            }]
    }
}).state('app.ui', {
    url: '/ui',
    template: '<div ui-view class="fade-in-up"></div>'
}).state('app.ui.buttons', {
    url: '/buttons',
    templateUrl: 'tpl/ui_buttons.html'
})
};

But i have a json array which i want to use as source of these states. That array looks like

var stateList =
[
    {
        name: 'app',
        val: {
            abstract: true,
            url: '/app',
            templateUrl: 'tpl/app.html'
        }
    }
    , {
        name: 'app.dashboard-v1',
        val: {
            url: '/dashboard-v1',
            templateUrl: 'tpl/app_dashboard_v1.html',
            resolve: {
                deps: ['$ocLazyLoad',
                    function ($ocLazyLoad) {
                        return $ocLazyLoad.load(['controllers/chart.js']);
                    }]
            }
        }
    }
    , {
        name: 'app.ui',
        val: {
            url: '/ui',
            template: '<div ui-view class="fade-in-up"></div>'
        }
    }
    , {
        name: 'app.ui.buttons',
        val: {
            url: '/buttons',
            templateUrl: 'tpl/ui_buttons.html'
        }
    }
];

I have seen many relevant posts but this one (Create states from array object in Angular ui-router) looks like exactly what i need. But I am unable to use it successfully because it does not include URLs. It results nothing for me.

What i want is just to replace .state({}).state({})... with a loop. If it is not valid then any alternative approach is ok as well. But target is to load all states from a json array Also it would be better if resolve option is supported, because i would prefer to use that lazy loading but thats not compulsory

Community
  • 1
  • 1
Sami
  • 8,168
  • 9
  • 66
  • 99

3 Answers3

1

This:

$stateProvider.state(...).state(...).state(...)

Could also be written:

$stateProvider.state(...);
$stateProvider.state(...);
$stateProvider.state(...);

i.e. $stateProvider.state() just returns $stateProvider so you can chain them if you want, there's no obligation to chain them or make all the calls together.

So just write a loop and register each state in turn.

Duncan
  • 92,073
  • 11
  • 122
  • 156
1

Try iterating over your JSON and registering states separately:

You do not have to chain the state method. The forEach iterates over your Array and registers a new state for every element. The first argument is the name and the second one is the config (val). You should take care that your config (val) has the pattern expected by stateProvider.state

stateList.forEach(function(item) {
  if (item.name && item.val) {
    $stateProvider.state(item.name, item.val);
  }
});
Sami
  • 8,168
  • 9
  • 66
  • 99
FelixMelix
  • 278
  • 1
  • 8
  • like Duncan said, you do not have to chain the state method. The forEach iterates over your Array and registers a new state for every element. The first argument is the name and the second one is the config (val). You should take care that your config (val) has the pattern expected by stateProvider.state – FelixMelix Mar 10 '16 at 13:27
0

Both the two answers collectively made the concept clear for me. And here is the working solution.

app.config(function ($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise('app/dashboard-v1'); //default url
    //stateList is a json array (in question)
    stateList.forEach(function (item) {
        $stateProvider.state(item.name, item.val);
    });
});
Sami
  • 8,168
  • 9
  • 66
  • 99