Dynamic partial arguments in AngularJS routing Dynamic partial arguments in AngularJS routing angularjs angularjs

Dynamic partial arguments in AngularJS routing


How about defining a single route with a paramater ?In angularjs v1.x you can defined as many routes you want with as many params xor query

.config(function($routeProvider, $locationProvider) {  $routeProvider   .when('/city/:slug', {    templateUrl: 'book.html',    controller: 'BookController',    resolve: {     // you can also retrieve some data as a resolved promise inside your route for better performance.  }})

ref: https://docs.angularjs.org/api/ngRoute/service/$route


appRouteProvider.when('/:city/:slug', {templateUrl : 'dafault.html',controller  :  'DefaultController',resolve:{    factory: function($routeParams, $http, $location, sharedParams){        var city = $routeParams.city;        var slug = $routeParams.slug;        var deferred = $q.defer();        sharedParams.getCurrentPageType($routeParams).then(function(t) {            if(t=='list'){                $location.path('/' + city + '/' + slug + '/list');                deferred.resolve();            }            else if(t=='single'){                $location.path('/' + city + '/' + slug + '/single');                deferred.resolve();            } else {                deferred.reject();            }        });        return deferred.promise;    }, }});appRouteProvider.when('/:city/:slug/list', {    templateUrl: '../../app/templates/list.html',    controller: 'ListsController',});appRouteProvider.when('/:city/:slug/single', {    templateUrl: '../../app/templates/single.html',    controller: 'SingleController',});

You can do it with separate routes. The idea is when user hits the main route it resolves first with the data from the backend. If the condition is met, resolve function will redirect to specific route if not it wont pass


Services in Angular cannot be injected in the configuration phase since they become available only in the run phase of an Angular application.

There is however a trick to load $http service in the config phase which you can use to load your cities/categories and set up your routes. Meanwhile, since controllers aren't registered up until the run phase, you may use the $controllerProvider to register your controllers beforehand in the configuration phase:

app.config(function ($routeProvider, $controllerProvider) {  $controllerProvider.register('ListController', ListController);  $controllerProvider.register('SingleController', SingleController);  // wire the $http service  var initInjector = angular.injector(['ng']);  var $http = initInjector.get('$http');  ...});

You can now call your API to get the cities (or whatever else) and iterate while registering each route:

  ...  // fetch the cities from the server  $http.get('/cities')  .then(function (response) {    var cities = response.data;    for(var i = 0; i < cities.length; i++){      $routeProvider      // assuming each city object has a `name` property      .when('/' + cities[i]['name'] + '/:slug', {        templateUrl: getTemplate(cities[i]['name']),        controller: getController(cities[i]['name'])      })    }  });  ...

Note that I'm using the getTemplate and the getController methods which return the templateUrl and the relevant controller name strings respectively using an ordinary switch expression. You can choose your own approach.

Plunkr Demo

Note:

While a function with the templateUrl route options property does work with setting up a custom template, but when you use a function alongside the controller property, Angular will consider it as the constructor for the controller. Therefore, returning the name of the controller in that function won't work.