AngularJS – How to use $routeParams in generating the templateUrl?

The question:

Our application has 2-level navigating. We want to use AngularJS $routeProvider to dynamically provide templates to an <ng-view />. I was thinking of doing something along the lines of this:

angular.module('myApp', []).
config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/:primaryNav/:secondaryNav', {
        templateUrl: 'resources/angular/templates/nav/'+<<primaryNavHere>>+'/'+<<secondaryNavHere>>+'.html'

I just don’t know how to populate the parts within the <<>>. I know the primaryNav and secondaryNav get bound to the $routeParams, but how do I access $routeParams here in order to dynamically serve up the template?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

This very helpful feature is now available starting at version 1.1.2 of AngularJS. It’s considered unstable but I have used it (1.1.3) and it works fine.

Basically you can use a function to generate a templateUrl string. The function is passed the route parameters that you can use to build and return the templateUrl string.

var app = angular.module('app',[]);

    function($routeProvider) {
            when('/', {templateUrl:'/home'}).
                    templateUrl: function(params){ return '/users/view/' + params.user_id; }

Many thanks to for the pull request.

Method 2

I couldn’t find a way to inject and use the $routeParams service (which I would assume would be a better solution) I tried this thinking it might work:

angular.module('myApp', []).
    config(function ($routeProvider, $routeParams) {
        $routeProvider.when('/:primaryNav/:secondaryNav', {
            templateUrl: 'resources/angular/templates/nav/'+$routeParams.primaryNav+'/'+$routeParams.secondaryNav+'.html'

Which yielded this error:

Unknown provider: $routeParams from myApp

If something like that isn’t possible you can change your templateUrl to point to a partial HTML file that just has ng-include and then set the URL in your controller using $routeParams like this:

angular.module('myApp', []).
    config(function ($routeProvider) {
        $routeProvider.when('/:primaryNav/:secondaryNav', {
            templateUrl: 'resources/angular/templates/nav/urlRouter.html',
            controller: 'RouteController'

function RouteController($scope, $routeParams) {
        $scope.templateUrl = 'resources/angular/templates/nav/'+$routeParams.primaryNav+'/'+$routeParams.secondaryNav+'.html';

With this as your urlRouter.html

<div ng-include src="templateUrl"></div>

Method 3

templateUrl can be use as function with returning generated URL. We can manipulate url with passing argument which takes routeParams.

See the example.

    templateUrl: function(params){
         return params.screenName +'/listUI'

Hope this help.

Method 4

Alright, think I got it…

Little background first:
The reason I needed this was to stick Angular on top of Node Express and have Jade process my partials for me.

So here’s whatchya gotta do…
(drink beer and spend 20+ hours on it first!!!)…

When you set up your module, save the $routeProvider globally:

// app.js:
var routeProvider
    , app = angular.module('Isomorph', ['ngResource']).config(function($routeProvider){

        routeProvider = $routeProvider;
            .when('/', {templateUrl: '/login', controller: 'AppCtrl'})
            .when('/home', {templateUrl: '/', controller: 'AppCtrl'})
            .when('/login', {templateUrl: '/login', controller: 'AppCtrl'})
            .when('/SAMPLE', {templateUrl: '/SAMPLE', controller: 'SAMPLECtrl'})
            .when('/map', {templateUrl: '/map', controller: 'MapCtrl'})
            .when('/chat', {templateUrl: '/chat', controller: 'ChatCtrl'})
            .when('/blog', {templateUrl: '/blog', controller: 'BlogCtrl'})
            .when('/files', {templateUrl: '/files', controller: 'FilesCtrl'})
            .when('/tasks', {templateUrl: '/tasks', controller: 'TasksCtrl'})
            .when('/tasks/new', {templateUrl: '/tasks/new', controller: 'NewTaskCtrl'})
            .when('/tasks/:id', {templateUrl: '/tasks', controller: 'ViewTaskCtrl'})
            .when('/tasks/:id/edit', {templateUrl: '/tasks', controller: 'EditTaskCtrl'})
            .when('/tasks/:id/delete', {templateUrl: '/tasks', controller: 'DeleteTaskCtrl'})
        .otherwise({redirectTo: '/login'});


// ctrls.js
app.controller('EditTaskCtrl', function($scope, $routeParams, $location, $http){

    var idParam = $;
    routeProvider.when('/tasks/:id/edit/', {templateUrl: '/tasks/' + idParam + '/edit'});
    $location.path('/tasks/' + idParam + '/edit/');


That may be more info than what was needed…

  • Basically, you’ll wanna store your Module’s $routeProvider var globally, eg as routeProvider so that it can be accessed by your Controllers.

  • Then you can just use routeProvider and create a NEW route (you can’t ‘RESET a route’ / ‘REpromise’; you must create a new one), I just added a slash (/) at the end so that it is as semantic as the first.

  • Then (inside your Controller), set the templateUrl to the view you want to hit.

  • Take out the controller property of the .when() object, lest you get an infinite request loop.

  • And finally (still inside the Controller), use $location.path() to redirect to the route that was just created.

If you’re interested in how to slap an Angular app onto an Express app, you can fork my repo here:

And this method also allows for you to keep the AngularJS Bidirectional Data-Bindings in case you want to bind your HTML to your database using WebSockets: otherwise without this method, your Angular data-bindings will just output {{model.param}}.

If you clone this at this time, you’ll need mongoDB on your machine to run it.

Hope this solves this issue!


Don’t drink your bathwater.

Method 5


.when('/enquiry/:page', {
    template: '<div ng-include src="templateUrl" onload="onLoad()"></div>',
    controller: 'enquiryCtrl'


// template onload event
$scope.onLoad = function() {
    f_tcalInit();  // or other onload stuff

// initialize
$scope.templateUrl = 'ci_index.php/adminctrl/enquiry/'+$;

I believe it is a weakness in angularjs that $routeParams is NOT visible inside the router. A tiny enhancement would make a world of difference during implementation.

Method 6

I’ve added support for this in my fork of angular. It allows you to specify

    .when('/:some/:param/:filled/:url', {

not sure this will get picked up as it is kind of against the grain for angular, but it is useful to me

Method 7

//module dependent on ngRoute  
 var app=angular.module("myApp",['ngRoute']);
    //spa-Route Config file
            .otherwise({template:'Not Found'});
   //aboutUs controller 

in index.html

<a ng-href="#/about/firstParam/secondParam" rel="nofollow noreferrer noopener">About</a>

firstParam and secondParam can be anything according to your needs.

Method 8

I was having a similar issue and used $stateParams instead of routeParam

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment