Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Routing in AngularJS - Can I retrieve data from server before setting up $routeProvider?

Is there any way to make a server hit to retrieve data before setting up all the routes on the $routeProvider? I want to be able to dynamically setup routes based on this remote data. I tried something like this:

angular.module("myApp").config(["$routeProvider", "$http", function($routeProvider, $http) {
    $http.get("myData").success(function(data) {
        $routeProvider.when(data.dynamicRoute, {
            //route definition
        }
        //or
        $routeProvider.when("/known/route", {
            redirectTo: data.dynamicRoute
        }
    });
}]);

but that results in the following error:

Unknown provider: $http from myApp

So, I understand that the config function is injecting providers and not services. However, I still want to know if I can somehow accomplish my end goal? I don't think I could do this with the $httpProvider, but please someone correct me if I'm wrong. If there's some fundamental reason why this just isn't possible, please explain. Any help with this would be much appreciated.

like image 441
dnc253 Avatar asked Apr 03 '13 06:04

dnc253


2 Answers

This is 100% working solution!

  1. Prepare your routes. They might be looked like this ones in json

    {"0":{"id":1,"when":"/","controller":"MainController","template":"app/views/site/main_inner.html"},"1":{"id":2,"when":"/firm/:firmID","controller":"CompanyController","template":"app/views/site/firm.html"},"2":{"id":3,"when":"/search","controller":"SearchController","template":"app/views/site/search.html"}}
    
  2. First, you have to make a global reference to RouteProvider

      var $routeProviderReference;
     var app = angular.module('myApp', []);
    
      app.config(['$routeProvider', function($routeProvider) {
      $routeProviderReference = $routeProvider;
      }]);
    
  3. Second, use method run to do an ajax call for routes.

       app.run(['$rootScope', '$http', '$route', function($rootScope, $http, $route) {
        //getting routes
        $http.get('routes.php').success(function (data) {
    
        angular.forEach(data, function (route) {
            $routeProviderReference.when( route.when, { templateUrl: route.template, controller: route.controller } );
        });
        $routeProviderReference.otherwise({ redirectTo: '/' });
        $route.reload();
    
    });
    
    }]);
    

For more info look at the ref bellow http://blog.brunoscopelliti.com/how-to-defer-route-definition-in-an-angularjs-web-app

like image 122
Stas Panyukov Avatar answered Nov 15 '22 11:11

Stas Panyukov


There is no way to do this.

A provider is a configurable service creator. They allow us to provide an API to use to configure their creation. And the configurability is what brings us to config blocks. These are used before services are available in order to configure their creation. So you can pass settings to $routeProvider or $httpProvider that it will use when it creates the $route and $http services, respectively.

Because the services are still being configured at this stage, the services themselves are not available for injection - they don't actually exist yet.

The $routeProvider allows us to configure routes, which must be running when our application starts. It wouldn't make sense to have routing start at some random point during the running of our application.

All this is to say that you can't start running your application, which is what using $http would mean, until after the configuration is done. So there's no way to define routes from remote data.


For what it's worth, I don't think I see the value in such dynamic routes anyway; they would be unpredictable by nature because they are built from data that is not static. This would totally break bookmarkability, which is the principal purpose of routing.

So I would ask why you feel the need to do this in the first place and then take a step back and see if this is really even the way it should ideally be done.

Feel free to post a comment to provoke further discussion.

like image 30
Josh David Miller Avatar answered Nov 15 '22 11:11

Josh David Miller