32

I'm using angular in an application which is, basically, a table with search results. Access to this table can be achieved via an url like http://myapp/?client=clientName

An angular controller is instantiated for the table, among other things, for opening a modal dialog (also angular-based with bootstrap-ui) with the row details.

These row details are brought via a service which has some common functionality for both controllers: the one for the table and the one for the modal.

Now, within this service, I have the following snippet to retrieve:

service.fetchRelatedElements = function(element, cb) {
  var url = '/search.json?results=20&type='+element.type;
  if ($location.search()['client']) {
    url += '&client=' + $location.search('client');
  }
  return doFetch(url, cb); // actual server json GET
};

The goal is to know if the table already has this specific client parameter set as a filter.

If I put a breakpoint at the beginning of this call, I see that $location.absUrl() returns the current browser URL (which, in my case, has the client parameter I'm interested in).

But $location.search() returns an empty object.

I am injecting the $location service within my service with the defaults (that is, not configuring it by a .config() call). And, as doc says:

The $location service parses the URL in the browser address bar (based on the window.location) and makes the URL available to your application.

Am I missing something? Shouldn't the URL, at this point, be parsed?

Thanks!


UPDATE: I've managed to make it work. The problem was exactly that I wasn't configuring at all the service. I did so because I assumed that in that way it would take defaults, but it seems that that's not the way it works.

3
  • Can you share the output of $location.absUrl()? This smells like a regexp problem. Commented Apr 29, 2013 at 21:24
  • Sure! It's http://localhost:3000/results?utf8=%E2%9C%93&client=mond&type=&submittedLowerBound=&submittedUpperBound=&commit=Filter. It's a rails app on the backend. Commented Apr 29, 2013 at 21:37
  • 4
    Can you share some code for your solution? Im having the same issue where $location.search() returns {} Commented May 16, 2013 at 1:35

5 Answers 5

43

I was having the same problem before I configured $locationProvider in my app's module config:

appModule.config(['$locationProvider', function($locationProvider) {
        $locationProvider.html5Mode(true);
    }]);
Sign up to request clarification or add additional context in comments.

3 Comments

with that way angular will fallback to the hashbang url if the browser not supports html5 mode, by the way someone knows how to get query params without html5 mode and router in angular?
Note also that when you set it to html5Mode, you must also have a base tag in the html file.
Also note you may need to add $locationProvider.hashPrefix(''); docs.angularjs.org/guide/migration#commit-aa077e8
12

If you don't want to specify the base tag, you can specify require base false.

myapp.config(function($locationProvider) {
    $locationProvider.html5Mode({
      enabled: true,
      requireBase: false
    });
});

Comments

5

When I encountered this problem, another thing that worked for me besides setting the configuration is to add "#" in front of the query string.

So if you are the one creating the query string, then changing
myapp/?client=clientName
to
myapp/#?client=clientName

allowed $location.search() to give me a non-empty object which you can then access each parameter using $location.search()['client']

1 Comment

Thanks. This comment should be in the official documentation. :)
4

The API for $location.search is pretty confusing. Calling

$location.search('client');

will set the search object to {client: true} and return $location. Furthermore, you have a typo client instead of 'client', so it's setting search to an empty object. So you probably want:

url += '&client=' + $location.search()['client'];

2 Comments

Thanks, Jmr, I fixed the typo. But the important thing is that, at that point, $location.search() returns just {}.
Sorry, I missed that you had put the breakpoint at the beginning of the question, I thought maybe $location.search(client) was overriding it. In that case I'm not sure what's going on, $location.search() parses your URL fine on my machine.
3

You can write a function that parses the $window.location.search based on this comment https://github.com/angular/angular.js/issues/7239#issuecomment-42047533

function parseLocation(location) {
    var pairs = location.substring(1).split("&");
    var obj = {};
    var pair;
    var i;

    for (i in pairs) {
        if (pairs[i] === "")
            continue;

        pair = pairs[i].split("=");
        obj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
    }

    return obj;
}

$scope.query = parseLocation($window.location.search)['query'];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.