Backbone history navigate not keeping hash in url - backbone.js

I want to use hashes in my urls. when i use the code below, the url goes to kart/:nid but not #kart/:nid as i want it to. I have not enabled pushState:true in my code so that should not be the problem.
Backbone.history.navigate('#kart' + "/" + this.model.get("nid"), { trigger: true});
When i remove the wildcard from the function, the url keeps the hash going to "#kart".
Why is the wildcard messing up this?
Appreciate any help!

A couple of things come to mind. Make sure you aren't explicitly setting {hashChange: false} in your code.
If you look at the documentation for navigate, you'll notice they're not explicitly specifying the hash. So try this instead
Backbone.history.navigate( "kart/" + this.model.get("nid"), { trigger: true} );

Thanks for helping guys! i found that the culprit was jquery mobile

Related

$location.search() not working

Update2:
$location just for ng.
so $location.search is ng's search
it parse url from mark like # or #! .
but $window.location handle the brower url
in my question, first url's ng search is empty
and second url's ng search is {code & state}
is it right?
Update1:
i found the *$window.location* got the right data.
is *$location* override the all things?
Question
i use angular-ui-router in my project. and i want to get search string from url,
like this: http://localhost:8080/?code=123456&state=auth#/api/oauth2_authorize
in app.config, i set:
$stateProvider.state("oauth2_authorize", {
url: "/api/oauth2_authorize?code&state",
template: "",
controller: function($location) {
var search = $location.search();
}
})
i think the search will be { code : 123456; state:auth} but no.
i try to change the url to : http://localhost:8080/#/api/oauth2_authorize?code=123456&state=auth
and it work.
somebody could tell me why? the html5mode is false.
i check the angularjs's document, and $location's sample show that, i can get the search string from both url.
and i try to use $urlRouterProvider , but it still empty.
what can i do?
Because, if you set html5mode to false, all your urls need to have #. Even if in your url state you dont have # .
For that reason
http://localhost:8080/?code=123456&state=auth#/api/oauth2_authorize doesn't work and
http://localhost:8080/#/api/oauth2_authorize?code=123456&state=auth
it does.
Check angularjs docs for $location and urls
I guess something wrong with AngularJs version you are using.
Which version are you using?
refer following link suggest the same issue and fix with HTML5Mode=true
https://github.com/angular/angular.js/issues/6198
Or just go through following pages, may be helpful to fix your issue.
https://github.com/angular/angular.js/issues/5964
https://github.com/angular/angular.js/issues/4607

in-page anchor with backbone

Hi everyone,
I am developing a backbone app and I went through one "big" problem, I can't find any useful thinking on internet but I can't imagine I am the only one to have this problem.
I just want to use basic in-page anchor with backbone like old time.
Example : I want to my page to go down to a section when I have #section at the end of the URL.
My backbone url path is site.com/#/page .... so of course site.com/#/page#section will freak out.
The only solution I found is to use push state but I don't really want to.
Is there another way to handle this behaviour ? even with another pattern or plugin .. but no push state.
Thanks very much,
jdmry
Here's how I'm doing it:
First, add Backbone.history.anchor
pathParts = Backbone.history.fragment.split('#')
Backbone.history.anchor = pathParts[1]
Then, use jQuery to scroll to the element
if (Backbone.history.anchor) {
$('html, body').animate({
scrollTop: $('#' + Backbone.history.anchor).offset().top - 10
});
}

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

Backbone.js and leading hash

I have the following problem. Some part of my Backbone application has url like:
site.ru/#profile
When the page is loaded URL changes to:
site.ru/profile
So, the hash was lost. So, I see the problem in navigate function of Backbone:
var routeStripper = /^[#\/]/;
...
var frag = (fragment || '').replace(routeStripper, '');
As I understand this code clean a hash at the begin of URL.
Is it true way to simply delete this line of code to fix the problem? Could you advise me some other ways to fix this.
TIA!
Backbone only removes the hash if you enable pushState.
Change Backbone.history.start({pushState: true}); to Backbone.history.start();
http://backbonejs.org/#Router
Seems Backbone.js is using / & # as delimiters, to pull out the root address & sub-directories. The / filtering needs tp stau tp get the "fragment". Try to just delete the # in that RegEx, but leave the rest of the line there. (& leave a comment in the code that you have done so! :)
I would also submit a bug report, since it is resending the link without the hash.
Having the same issue, and some others with us ;-) (see GitHub issue)
I've fixed this for now by not listening to hash changes, like so:
Backbone.history.start({
pushState: true,
hashChange: false,
root: '/'
});
This seemed to work for me.

Resources