Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm struggling with passing and reading multiple query string parameters in a route.

$routeProvider.when("/joboffers:keywords:location", {
    controller: "jobOffersController",
    templateUrl: "/App/Views/JobOffer/All.html"
});

This is the search page:

$scope.searchJobOffer = function () {
    var vm = $scope.jobOfferSearchViewModel;
    var path = "/joboffers?keywords=" +( vm.keywords || "") + "&location=" + (vm.location || "");
    $location.path(path);
}

And this is the JobOffersController:

'use strict';
app.controller('jobOffersController', ['$scope', '$routeParams', 'jobOfferService', function ($scope, $routeParams, jobOfferService) {
    $scope.jobOffers = [];

    function init() {
        var keywords = $routeParams.keywords;
        var location = $routeParams.location;
    }

    init();
}]);

Reading the $routeParams is not working at all. If I pass "developer" as a keyword and "New York" as location, the $routeParam object looks like this:

{keywords: "?keywords=developer&location=New Yor", location: "k"}

Can somebody tell me what I'm doing wrong? Thanks in advance.

P.S. Is it possible that this is because of a wrongly configured route? When I navigate via the searchJobOffer function, it encodes the URL to this: http://localhost:49380/#/joboffers%3Fkeywords=developer&location=london and if I try to use this url http://localhost:49380/#/joboffers?keywords=developer&location=london, the routing system drops me to the default route (#/home)

share|improve this question
    
Please post the code of the JobOffersController. –  JimmyRare Nov 1 '14 at 20:18
    
stackoverflow.com/a/24981775/356380 –  Whisher Nov 1 '14 at 20:24
    
$location.search() returns an empty object. –  laszlokiss88 Nov 1 '14 at 20:26
    
$routeParams are only updated after a route change completes successfully. You sure this is the case? –  JimmyRare Nov 1 '14 at 20:30
    
Since the controller is loaded, I'm pretty sure. But just to test it, I've moved the init() to a setTimeout() with 5 secs, and the $routeParams has the same value. –  laszlokiss88 Nov 1 '14 at 20:36

1 Answer 1

up vote 1 down vote accepted

$routeProvider does not match on query strings, only routes. Also, you're setting a full url to $location.path() and $location.path() only takes the path piece of the url. To set the entire URL including query string you need to use $location.url().

Here are a few options:

1. Use pretty URLs instead

$routeProvider.when("/joboffers/:location/:keywords", {
  controller: "jobOffersController",
  templateUrl: "/App/Views/JobOffer/All.html"
});

$scope.searchJobOffer = function () {
  var vm = $scope.jobOfferSearchViewModel;
  var path = "/joboffers/" + (vm.location || "") + "/" + ( vm.keywords || "");
  $location.path(path);
};

app.controller('jobOffersController', ['$scope', '$routeParams', 'jobOfferService', function ($scope, $routeParams, jobOfferService) {
  $scope.jobOffers = [];

  function init() {
    var keywords = $routeParams.keywords;
    var location = $routeParams.location;
  }

  init();
}]);

2. Only match on the job offers path and pull the params from $location.search()

(note the use of $location.url() instead of $location.path())

$routeProvider.when("/joboffers", {
  controller: "jobOffersController",
  templateUrl: "/App/Views/JobOffer/All.html"
});

$scope.searchJobOffer = function () {
  var vm = $scope.jobOfferSearchViewModel;
  var url = "/joboffers?keywords=" +( vm.keywords || "") + "&location=" + (vm.location || "");
  $location.url(url);
};

app.controller('jobOffersController', ['$scope', '$location', 'jobOfferService', function ($scope, $location, jobOfferService) {
  $scope.jobOffers = [];

  function init() {
    var search = $location.search();
    var keywords = search.keywords;
    var location = search.location;
  }

  init();
}]);

3. If you need to match the route AND the query string, try something more robust like angular-ui-router

$stateProvider.state("JobOffers", {
  url: '/joboffers?keywords&location',
  controller: "jobOffersController",
  templateUrl: "/App/Views/JobOffer/All.html"
});

$scope.searchJobOffer = function () {
  var vm = $scope.jobOfferSearchViewModel;
  var url = "/joboffers?keywords=" +( vm.keywords || "") + "&location=" + (vm.location || "");
  $location.url(url);
};

app.controller('jobOffersController', ['$scope', '$stateParams', 'jobOfferService', function ($scope, $stateParams, jobOfferService) {
  $scope.jobOffers = [];

  function init() {
    var keywords = $stateParams.keywords;
    var location = $stateParams.location;
  }

  init();
}]);
share|improve this answer
    
Thank you very much for this detailed answer, I think I'll go with the second option. –  laszlokiss88 Nov 1 '14 at 20:56

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.