AngularJS: How to provide a search facility and cause route change passing in params? - angularjs

I need to be able to offer a search facility that will show results, I suppose allowing this route to be be bookmarkable.
What are my options here?
Do I just need to create a new route and place a resolve on there so that i can call my rest service and only display the page when its ready. Then i presume I would force a change of route via my existing controller ?
Problem I see is that I need to store a number of items on the URL, all the search params otherwise it won't be bookmarkable. Is the only way to do this by passing ugly querystrings ?
And how would I access the querystrings from angularjs so i could extract my params that i need to send along to the rest service.
I have tried googling for something similar or an example but I can't seem to find anything.
Has anyone done something similar, any pointers would be really helpful.
thanks

The $location service has a search method that acts as both a getter and a setter for querystring parameters.
It will return an object that corresponds to your parameters:
{
foo:123,
bar:'Kittens'
}

Related

Use Angular's $location to get URL parameters from URL string instead of current URL

Can I (re)use Angular's $location or another Angular module to get URL parameters from a url? Or do I need to add (yet) another separate JS package to do this?
I have a URL string which I want to get the URL parameters from (aka searchstring). I know there's logic to do this in Angular.js, because $location has the search method. This returns the url parameters part as an object. For instance for a url https://www.domain.org/cool?minPrice=40&maxPrice=50 I can get the maxPrice value using: $location.search().maxPrice.
But this works only for the current url in the browser bar. I'm setting up an ngMock function that has to get url params from a URL passed in as a string parameter. I DON'T want a DIY solution as there is so much debate about what is correct, performant, etc due to things you might not think of it at first like:
- bad performance of regexp
- needing to url encode parameters
- order dependence, etc.
So I'd love to get this gift-wrapped. And ideally as an included-in-Angular solution so there's also no work for wrapping things up in an Angular service :P.
Note: If it's not possible I'll probably use uri.js, which I used to satisfaction in a non-Angular project a while ago.

Angularjs route with hidden parameters like a http post

Can I get hidden parameters like a http post with $location?
Concept of what I'm thinking:
$location.param(key, value);
$location.path('/myPLace');
I think, you like to share values/parameter between different routes?
The example from #mobabur94 works, but the parameter is not hidden.
To hold parameters between routes, you could use a service. Take a look at this:
Angularjs, passing scope between routes

AngularJS change url with $location

I'm trying to change the URL with AngularJS,
but not with a redirect, just change the URL
after an event.
What I need is this:
www.myurl.com/inbox/1 to this www.myurl.com/inbox/25
In other words, just change the last Id.
I'm trying to do this:
$location.path('/inbox/'+id);
But what I'm getting is this:
www.myurl.com/inbox/1#/inbox/25
Angular enforces the idea of one page web app. Browsers don't take any actions on change of anything after '#' value. So the best practice is to add variable attributes in url after '#' value which will keep the base url and attribute look clean on browser's address bar as well as solve your problem. My advice is to keep username, page no. , or any specific attribute id after '#' value.
In your case you should use something like above said
www.myUrl.com/#/inbox/25
or
www.myUrl.com/inbox/#/25
usually angular URLs look like
www.myurl.com/#/inbox/1
in which case
$location.url('/inbox/25');
should work for you
For that you should use .url() instead of .path()
$location.url(`/inbox/${id}`)

AngularJS routing for dynamic urls, how?

I'm trying to understand how can i configure my angularJS routing given the following case:
We have a search page where we display the search results based on tags provided (1..n tags). we would like that a user to be able to parse enter a url as the following and our system to do the search and show the respective results.
The url format should be:
http://mywebsite.com/search/<term1>/<term2>/<termN>...so it could be different number of terms.
I was looking into the route provide and couldn't figure out a way to do it dynamically.
i saw that i could put in the routeprovid:
.when('/search/:searchParams',... but that handles only when i have one term...is there anyway to configure it to take as many terms as is given?
Does this help you at all? Seems to support dynamic routing and you could probably cut apart the :name parameter to do what you wish, perhaps.
http://gregorypratt.github.io/AngularDynamicRouting/
Ken
You could try base64ing your searchParams:
.when('/search/:searchParams', {controller:'SearchCtrl'})
function SearchCtrl($routeParams, $location){
//Assuming your params are an array like ['param1', 'param2', 'param3']
//You could easily adapt this to base64 a JSON object
function encodeParams(params){
return window.btoa(params.join(';'));
}
function decodeParams(string){
return window.atob(string).split(';');
}
var searchParams = decodeParams($routeParams.searchParams);
scope.search = function(params){
$location.path('/search/' + encodeParams(params));
}
}
My solution may be looks not so glad, but it's works at least:
You may organize your routs in way
yoursite.com/term1Name/**:param1**/term2Name/**:param2**/term3Name/**:param3**
To make it's clear, you may do your routes seems like REST routes. For example I'm want to go to a list of a services:
www.yoursite.com/servises/
Go to the one of the services:
www.yoursite.com/servise/:id
And if I'm want to see some of the service details, I'll do:
www.yoursite.com/servise/:id/details
and so
www.yoursite.com/servise/:id/detail/:id

AngularJS: How to clear query parameters in the URL?

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();
}

Resources