Thursday, July 25, 2013

Angular JS: Routing Views Past the Config Section



I recently had to deal with a situation where I had to dynamically setup the routes of my views in an angular based app. 

The deal was: I have an index html with a container of features (ul), and each list item represents a feature in my app. naturally, a click on a list item (feature) should render the appropriate view into the ng-view. The problem is - the list is bound to a collection in the scope of the controller, and that collection is fetched using ajax with $http. 

Problem: in angular, $urlRouterProvider is only available in the config section, and you have to define the routes using $urlRouterProvider. 

However,er the config section cannot have $http calls. 

The solution: saving a reference to the  $urlRouterProvider in a global variable, and then using that reference to set the routes later on when $http can be used. 

Code:

Yellow - Config Section - can use $urlRouterProvider
Red - Run Section - can use $http, but not  $urlRouterProvider - use the $urlRouterProviderRef  instead.

'use strict';

var $stateProviderRef = null;
var $urlRouterProviderRef = null;
var $featuresRef = null

angular.module('webtu', ['webtu.common.filters', 'webtu.common.directives', 'webtu.common.services',
    'webtu.common.controllers', 'webtu.dnt.controllers', 'webtu.sitesafety.controllers', 'ui.state']).
    config(function ($stateProvider, $urlRouterProvider) {  
        $stateProviderRef = $stateProvider;
        $urlRouterProviderRef = $urlRouterProvider;    
    }).factory('featuresData', function ($http) {
        return{
            all : function() {
                return $http({
                    url: '/api/features',
                    method: 'GET'
                })
            }
        }
    }).run(function (featuresData) {
          featuresData.all().success(function (data) {    
                $featuresRef = data;        
                angular.forEach(data, function(value, key){
                  $stateProviderRef.state(value.title, {url:value.url, templateUrl:value.templateUrl, controller:value.controller });               
                });                            
                //$urlRouterProviderRef.otherwise(data.defaultUrl);
            },
            function (errorMessage) {
        });
        
    });


No comments:

Post a Comment