How to pass URL query parameters through templateUrl in $routeProvider?

10,774 views
Skip to first unread message

Chris Staymates

unread,
May 24, 2013, 12:56:25 PM5/24/13
to ang...@googlegroups.com
Suppose I have configured my route provider as such.  There are no controllers configured in my route on purpose.

var module = angular.module('MyModule', [], function ($routeProvider) {
    $routeProvider
        .when('/home', {templateUrl: 'home.php'})
        .when('/page/:someParam', {templateUrl: 'page.php',}).
        .otherwise({redirectTo:'/home'});
});

However, I know decide that I need to actually pass the value of :someParam to the server to do "some work"; basically I want the following request to goto my server: page.php?param=<value of :someParam>  How would I accomplish this?

Things I have tried:
- referencing :someParam in the templateUrl results in the following query string: page.php?param=:someParam
- injecting $routeParamsProvider into the configuration block (along with $routeProvider).  This did not seem to add valuable information, since the route is configured once and this shoudl be dynamic behavior.
- modified the configuration to look like the following.  This successfully resulted in the location showing the correct URL, but did not dispatch this URL to the server.

.when('page/:someParam', {
    templateUrl: 'page.php',
    redirectTo: function(pathParams, path, search) {
        return 'page/'+pathParams[someParam]+'/?param='+pathParams[someParam];
    }
}

I am well aware that I could limit the users interaction with the link that causes this route change to trigger (through ng-show, or just plain php).  I am also aware that I could limit functionality on 'page.php' itself in a controller.  Neither of these solutions fit my requirements.

Thank you for any help you can offer!

Jeremy Wilken

unread,
May 24, 2013, 3:58:07 PM5/24/13
to ang...@googlegroups.com
Angular doesn't look at query params, it only looks at the path to load the template. I have to ask the big question first, why are you asking for the html from PHP? Also why can you not use angular directives to control the display of the content? That would be the best approach so you aren't fighting Angular. 

In this situation, I can't think of a way without hacking Angular to pass variables. A route parameter :someParam is only made available via the $routeParams service. Typically you access the $routeParams in the controller, but you don't have any. The only idea I have is to intercept the requests before they go to the server. You can do this in your application module config method like below. The biggest drawback is you are then going to be putting a lot of logic in an odd location that will make the application hard to follow and eventually difficult to maintain. 

angular.module('myApp', []).config(function($httpProvider) {
  $provide.factory('MyHttpInterceptor', function ($q) {
    return {
      // On request success
      request: function (config) {
        // Do any request transformation here, data is in the config variable. This applies to any request, so you'll have to determine a logical way to detect which xhr requests needs to be modified, and how.
        return config || $q.when(config);
      }
    };
  });

  $httpProvider.interceptors.push('MyHttpInterceptor');
});

Leo

unread,
May 27, 2013, 5:07:37 AM5/27/13
to ang...@googlegroups.com
One option which might suit your requirements is to use a simple template with an ng-include attribute. You then use a controller to populate the include:

angular.module('app').controller('pageRouteCtrl', ['$scope', '$routeParams' ,function($scope, $routeParams){
$scope.templateUrl = "/page/" + $routeParams.someParam;
}]);

var module = angular.module('MyModule', [], function ($routeProvider) {
    
var template: '<div ng-include="templateUrl">Loading...</div>';
$routeProvider
        .when('/home', {templateUrl: 'home.php'})
        .when('/page/:someParam', {template: template, controller: 'pageRouteCtrl'}).
        .otherwise({redirectTo:'/home'});
});

Lucas Paulger

unread,
May 30, 2013, 5:07:14 AM5/30/13
to ang...@googlegroups.com
This seems like it could potentially be related to what I'm trying to do; I want to add a cache-busting query param to all my templateUrl requests; would intercepting all *.html requests and appending the query param make sense?

Jeremy Wilken

unread,
May 30, 2013, 10:57:05 AM5/30/13
to ang...@googlegroups.com
You can use my example above to intercept all requests, and then you would just conditionally apply the change after you check for the ending to be .html.

I used this to log requests into localstorage for debugging. It also lets you specify 'requestError', 'response' and 'responseError' methods which have one parameter of the response or rejected promise if failed.

I put a more complete example on Github.

Lucas Paulger

unread,
Jun 4, 2013, 11:53:56 AM6/4/13
to ang...@googlegroups.com
This doesnt work for me because my $httpProvider object looks like this:

    Constructor {defaultsObjectresponseInterceptorsArray[0]$getArray[7]}

but doesnt have interceptors property. What version of angular are you using? I'm currently on 1.0.7 - latest stable release
Or did I miss something?

Thanks

Jeremy Wilken

unread,
Jun 4, 2013, 12:02:58 PM6/4/13
to ang...@googlegroups.com
I've tested it in the 1.1.x branch. It might not work on the 1.0.x branch. In 1.0.x you can use the responseInterceptors property, which is documented on the current API docs. In 1.0.x it mentions a requestInterceptors property in the docs, but it doesn't exist in the object. I haven't tracked it down, but perhaps if you populate it the same way as the responseInterceptor, angular might pick up the property during execution.

Lucas Paulger

unread,
Jun 5, 2013, 10:52:13 AM6/5/13
to ang...@googlegroups.com
Thanks, I'll keep looking into this; or attempt to run the 1.1.x version :).

Tyler Palesano

unread,
Jul 15, 2015, 2:17:19 PM7/15/15
to ang...@googlegroups.com
This worked for me with some minor tweaks in AngularJS 1.3.16. Asp.NET MVC is the server-side language used to build my template, but the idea of passing query string (or Search) parameters to the server is the same.

With these changes, if the user put the following Url into their browser:


Then the request to asp.net MVC would be for the following:


angular.module('app').controller('pageRouteCtrl', ['$scope', '$window' ,function($scope, $window){
$scope.templateUrl = "/MVC/page" + $window.location.search;
}]);

var module = angular.module('MyModule', [], function ($routeProvider) {
    
var template = '<div ng-include="templateUrl">Loading...</div>'; //Changed : to =
$routeProvider
        .when('/home', {templateUrl: 'home.php'})
        .when('/page', {template: template, controller: 'pageRouteCtrl'}). //Deleted :someParam
        .otherwise({redirectTo:'/home'});
});

Reply all
Reply to author
Forward
0 new messages