I'm developing a search app with angular using ui-router.
Requirements:
The search form has too many fields and all have to be optional.
Users should share with another users the URL that display the page with the result list. (So I need to use querystring)
So I could have urls like
path/to/url/list?p=123&v=876
path/to/url/list?c=yes&a=true&p=123
path/to/url/list?z=yes&c=yes&a=true&p=123
path/to/url/list?z=yes&v=876&a=true&p=123
And endless combinations. I know that I can use $location.search() to get all params in json format. That is great! but the question is How can I define the url state with ui-router? Define explicitly all params in the url is not an option. I have read many post but I didn't find a concrete answers.
If you're getting parameters from $location you don't need to define them in state explicitly.
I think, the best way is to use 'resolve' property of $stateProvider configuration:
$stateProvider.state('mystate', {
// Some code here
resolve: {
queryData: ['$location', ($location) => {
$location.absUrl(); // Contains your full URI
return true;
}]
}
});
It's kind of initialization. After that, ui-router will cut URI, but you will store needed data. This case also works fine, when user passing URI directly in browser address input.
Also you can try to set $urlRouterProvider with $urlMatcher for this purposes, but it will be more difficult.
I'm trying to demonstrate something using url-query parameters using plunker, but I can't even get the parameters to show up (and then consequently not demonstrate my original issue).
I have created a simple plunker where the states url property looks like this: url: '/root?firstParam'
What I want then is to populate $stateParams.firstParam with whatever I write in the url of the browser for that queryParameter.
Plunker, plunkerWithParameter?firstParam=foo
I would imagine that $stateParams.firstParam would be undefined for the first url, but set to "foo" for the second. But it's undefined in both cases.
How can I get the $stateParams.firstParam to be set?
Edit: It seems that it is actually possible (#Rogerio Soares answer proves this). Keeping my answer here because there was an other error in the code.
There is no way to get the parameters from the browsers search bar in a Plnkr app since it is running in an iFrame. I fixed another problem of yours below:
I added the parameter to your otherwise statement like this:
$urlRouterProvider.otherwise('/root?firstParam=test');
The problem is that you redirected to root when no other route was found, and you didn't specify any parameters to the route.
Updated PlunkR: https://plnkr.co/edit/OxEGVkhzBO332ym3q8fV?p=preview
my two cents : As #Johannes Ferner said Plunker use iframe, but you can at least get your url with document.referrer
It is a little hacky but it work :D
$scope.parameters = [];
var url = document.referrer;
var props = url.split("?")[1]
.split("&")
.map(function(o){
return o.split("=");
});
console.log(props);
for(var i = 0; i < props.length; i++){
var prop = props[i];
console.log(prop);
if($stateParams.hasOwnProperty(prop[0])){
$scope.parameters.push({name: prop[0], value:prop[1]});
}
}
https://plnkr.co/edit/Cejgj1cLJnwQT2LzjsRm?firstParam=foo&p=preview
the Problem is that the plnkr is running within iFrames, so the URL you tried is simply wrong.
Try this one:
https://plnkr.co/edit/jV2pdV6q8g8QZ132Qu3A
I have added a Link to your root state with the first-parameter set to 'Yeah' like this:
<a ui-sref="root({firstParam: 'YEAH'})">Go to Root with Firstparam = "YEAH"</a>
Which results to this URL: https://run.plnkr.co/roo/root?firstParam=YEAH.
Wrong: If you open this URL directly in the browser, the query-params are correctly passed to your AngularJS Application and set to $stateParams.firstParam
Correct: I did not found a way to have a permanent URL to the plnkr without the code being embedded in an iframe.
I am trying to get query strings to work in my Angular setup, but it is behaving weirdly.
When i go to a URL like this:
http://localhost:3000/?query=test
The URL changes and removes anything after the '=' to end up with:
http://localhost:3000/?query
Has anyone had this problem before?
I am currently using Angular UI Router with defined states and HTML 5 mode. I have also tried specifying the query parameter in the route as below:
.state('home', {
url: '/?referrer',
templateUrl: 'app/views/home/home.html',
controller: 'mainController'
})
UPDATED........
OK. In my controller i had this:
var referrerURL = $location.search('referrer');
Removing this, fixes the issue. Why would this cause the problem?
For $location.search() method, you should use it like this:
$location.search('key','value').
If you don't set the value, it would be "true" by default.
More information here
Thanks for all your input.
I fixed this by changing my controller to use:
var referrerURL = $location.search().referrer;
I am hitting a REST endpoint at
www.example.com/resource/id
What is the best way for me to extract id from an angular module controller?
I have looked into using $routeProvider
$routeProvider.when('/resource/:id', {}).otherwise(...)
This will only work if I set
$locationProvider.html5mode(true)
If it is not set to true, it always ends up in the otherwise clause when I hit www.example.com/resource/8
How can I get this to work even if I don't set $locationProvider.html5mode to true?
I think you're looking for $route.current.params, I use angular-ui's ui-router ui-router, in which case you would use $stateParams.
use www.example.com#/resource/8 instead www.example.com/resource/8
just replace following code:
$routeProvider.when('/resource/:id', {}).otherwise(...)
with the:
$routeProvider.when('resource/:id', {}).otherwise(...)
/resource/:id ths take absolute url pattern. and resource/:id take relative url pattern.
so i think this will help you without setting of html mode true.
My AngularJS application needs to have access to the user's LinkedIn profile. In order to do that I need to redirect the user to a LinkedIn URL which contains a callback redirect_uri parameter which will tell LinkedIn to redirect the user back to my webapp and include a "code" query param in the URL. It's a traditional Oauth 2.0 flow.
Everything works great except that LinkedIn redirects the user back to the following URL:
http://localhost:8080/?code=XXX&state=YYY#/users/123/providers/LinkedIn/social-sites
I would like to remove ?code=XXX&state=YYY from the URL in order to make it clean. The user does not need to see the query parameters I received from LinkedIn redirect.
I tried $location.absUrl($location.path() + $location.hash()).replace(), but it keep the query params in the URL.
I am also unable to extract the query parameters, e.g. "code", using ($location.search()).code.
It seems like having ? before # in the URL above is tricking Angular.
I use
$location.search('key', null)
As this not only deletes my key but removes it from the visibility on the URL.
I ended up getting the answer from AngularJS forum. See this thread for details
The link is to a Google Groups thread, which is difficult to read and doesn't provide a clear answer. To remove URL parameters use
$location.url($location.path());
To remove ALL query parameters, do:
$location.search({});
To remove ONE particular query parameter, do:
$location.search('myQueryParam', null);
To clear an item delete it and call $$compose
if ($location.$$search.yourKey) {
delete $location.$$search.yourKey;
$location.$$compose();
}
derived from angularjs source : https://github.com/angular/angular.js/blob/c77b2bcca36cf199478b8fb651972a1f650f646b/src/ng/location.js#L419-L443
You can delete a specific query parameter by using:
delete $location.$$search.nameOfParameter;
Or you can clear all the query params by setting search to an empty object:
$location.$$search = {};
At the time of writing, and as previously mentioned by #Bosh, html5mode must be true in order to be able to set $location.search() and have it be reflected back into the window’s visual URL.
See https://github.com/angular/angular.js/issues/1521 for more info.
But if html5mode is true you can easily clear the URL’s query string with:
$location.search('');
or
$location.search({});
This will also alter the window’s visual URL.
(Tested in AngularJS version 1.3.0-rc.1 with html5Mode(true).)
Need to make it work when html5mode = false?
All of the other answers work only when Angular's html5mode is true. If you're working outside of html5mode, then $location refers only to the "fake" location that lives in your hash -- and so $location.search can't see/edit/fix the actual page's search params.
Here's a workaround, to be inserted in the HTML of the page before angular loads:
<script>
if (window.location.search.match("code=")){
var newHash = "/after-auth" + window.location.search;
if (window.history.replaceState){
window.history.replaceState( {}, "", window.location.toString().replace(window.location.search, ""));
}
window.location.hash = newHash;
}
</script>
If you want to move to another URL and clear the query parameters just use:
$location.path('/my/path').search({});
Just use
$location.url();
Instead of
$location.path();
If you are using routes parameters just clear $routeParams
$routeParams= null;
How about just setting the location hash to null
$location.hash(null);
if you process the parameters immediately and then move to the next page, you can put a question mark on the end of the new location.
for example, if you would have done
$location.path('/nextPage');
you can do this instead:
$location.path('/nextPage?');
I've tried the above answers but could not get them to work. The only code that worked for me was $window.location.search = ''
I can replace all query parameters with this single line: $location.search({});
Easy to understand and easy way to clear them out.
The accepted answer worked for me, but I needed to dig a little deeper to fix the problems with the back button.
What I noticed is that if I link to a page using <a ui-sref="page({x: 1})">, then remove the query string using $location.search('x', null), I don't get an extra entry in my browser history, so the back button takes me back to where I started. Although I feel like this is wrong because I don't think that Angular should automatically remove this history entry for me, this is actually the desired behaviour for my particular use-case.
The problem is that if I link to the page using <a href="/page/?x=1"> instead, then remove the query string in the same way, I do get an extra entry in my browser history, so I have to click the back button twice to get back to where I started. This is inconsistent behaviour, but actually this seems more correct.
I can easily fix the problem with href links by using $location.search('x', null).replace(), but then this breaks the page when you land on it via a ui-sref link, so this is no good.
After a lot of fiddling around, this is the fix I came up with:
In my app's run function I added this:
$rootScope.$on('$locationChangeSuccess', function () {
$rootScope.locationPath = $location.path();
});
Then I use this code to remove the query string parameter:
$location.search('x', null);
if ($location.path() === $rootScope.locationPath) {
$location.replace();
}