Allowing both html5 and hashbang mode - angularjs

My question is similar to this one, but my goal is to make the hashbang URLs silently redirect to the html5Mode style. I mean, when
example.com/#!/hello
gets entered, it should be silently changed to
example.com/hello
in order for existing links to stay valid. Compatibility with old browsers doesn't matter (as AFAIK everything supported by angularjs 1.3 works with the html5Mode).
Maybe I'm just misunderstanding the answer, but I can't see it there. I've got the html5Mode working without problems, but I sort of want two in one.

That's how it's working in mine and I'm not doing anything special? If I type mysite.com/angularapp/#/accounts/29 using Chrome, it gets replaced with mysite.com/angularapp/accounts/29
My routing config contains:
function($locationProvider) {
$locationProvider.html5Mode(true).hashPrefix("");
}
I'm on Angular 1.2.21, I'm not sure if that behavior would have changed on 1.3.x.

You can do it manually in JS with something liek this:
window.location.replace(
window.location.href.replace(new RegExp("^([^?]+/)#!/(.*)$"),
function (all, s1, s2) {
return s1 + s2;
}
)
);

Related

angular puts slash in index.php#/todiv so icant go todiv

This happens nearly always.
AngularJS puts slash in index.php#/gohere, so i can't go to "gohere".
Why angular puts? and how to prevent it from putting slash between index.php#/gohere?
normally it should be like this index.php#gohere, doens't it?
edit:
now i changed html alittle. it does like this now.
http://localhost/subsite/#/here
The hash inside the URL is called "Hashbang Mode".
You can add an option to your app.config() section
that turns off the default hashbang mode and activates
the HTML5-history based mode:
$locationProvider.html5Mode(true);
This mode allows you to use URLs without the hash,
e.g.
http://localhost/subsite/here
instead of
http://localhost/subsite/#/here
You can find more information about the modes in the official angular JS documentation:
https://docs.angularjs.org/guide/$location
(scroll down to "Hashbang and HTML5 Modes")

How to make Angular router (or ui-router) accept routes like `#foo` instead of redirecting to `#/foo`?

Terminology
#foo: slashless scheme
#/foo: slashy scheme
Background
There are certain legacy parts of the application which use (and rely on) the slashless scheme. I would like to introduce Angular routing (probably with ui-router) in a non-destructive way, such that doesn't interfere with the legacy routing so that part of the application could be gracefully phased out over time. Once that happens the all-angular app could switch to the slashy scheme all at once.
So far
I tried setting $locationProvider.hashPrefix('') to an empty string, but it seems you can only set the string between # and /, so that didn't work.
Options
It seems I can either
rewrite legacy parts of the app, or
rewrite Angular's $locationProvider.hashPrefix to include '/' by default. Therefore setting it to '' would become meaningful.
Both of these options seem very time-consuming.
Do you know about a better way to make Angular recognize the slashless scheme?
You can try using redirects!
With ui-router:
app.config(function ($urlRouterProvider) {
// when there is an 'old' route, redirect to new one
$urlRouterProvider.when('foo', '/foo');
// You can also use regex for the match parameter
$urlRouterProvider.when(/(\w+)/i, '/$1'); // UNTESTED!!!!!!
})
Reference about ui-router wiki
I'm sorry but hashtags are quite hard to test in plunkers/fiddles, so i'm not providing one for now...

Adding a hash prefix at the config phase if it's missing

I am now integrating phantom in my Angularjs-based web application.
This fine article says that I should call the $locationProvider.hashPrefix() method to set the prefix to '!' from SEO reasons(allow crawlers to intercept the _escaped_fragment component of the URL).
The problem is that I haven't though of the earlier, and some of my URLs look as following:
#/home.
I though perhaps there is a way that I can implant this '!' char into the begging of the URL programmatically(in case it is not already there) at the config function of the APP, instead having to edit a lot of markup manually.
I've had similar problem and manually (search/replace) went through all the links and fixed them.
The other problem I had was the external sites were using the old format i.e.
http://plinkplink.net/#/event/3
instead of the new format
http://plinkplink.net/#!/event/3
The fix I did for that is not strictly speaking angularjs idiomatic but it does the job. I've added this script to the header of my page. It simply redirects pages with # to pages with #!:
<script>
var loc = window.location.href
if (loc.indexOf("#") != -1 && loc.indexOf("#!") == -1 ){
window.location.href = loc.replace("#", "#!");
}
</script>
I hope it helps.
Are you linking to the # value? ie - <a href="#/my/page"> If so, you shouldn't be. You should be linking to the url without the # prefix and I believe it'll solve your issue.

AngularJS appending path after url?

I'm new to AngularJS. So far I have been working with a page in root (/), and I haven't seen any issues with the navigation.
Now I added a path - "entries". I see AngularJS is appending the path again, so
http://localhost:9000/entries
becomes:
http://localhost:9000/entries#/entries
And also a request with parameters, like:
http://localhost:9000/entries?par1=a&par2=1
becomes:
http://localhost:9000/entries?par1=a&par2=1#/entries?par1=a&par2=1
I read: $location doc
But still I don't quite understand what's going on here. Is this correct behaviour? If not, how do I turn it off?
This is the correct behavior. Changing paths in angular does not actual correspond to a change in the URL itself, just the fragment (what comes after the #). This is how angular (and JS frameworks in general) keep track of your location and changes it without refreshing.

possible to disable $locationProvider and $routeProvider?

Can I disable these fellas? I am using angular.js in asp.net mvc app, and I don't need angular to control anything related to address bar or the links...
Right now in html5 mode disabled ($locationProvider.html5Mode(false)) it adds hash and action method's name to the address-bar, for example: you go to \Home\index, it navigates and then address bar text changes into Home\index#\index. ain't that's annoying?
if I enable html5 mode it stops loading pages at all (except the initial). I try going from initialy loaded page to another - it changes the address-bar's text (without adding hashtag thing this time) but won't load the page itself. ain't that frustrating?
A makeshift solution exists here AngularJS 1.1.5 - automatically adding hash tag to URLs
The answer explains the first step (as explained above, with the addition of the new hash-prefix)
yourApp.config(['$locationProvider', function($locationProvider){
$locationProvider.html5Mode(true).hashPrefix('!');
}]);
The first bit handles Angular interfering with your address-bar visually, but now clicking on any links doesn't function properly as (read: history.pushState)
So, the workaround, as pointed out by user #Kevin Beal is some variation of setting the target of the <a> to _self
$('a[href]').attr({'target':'_self'})
or on a case-by-case basis:
Foo
Bar
Although, for the sake of convenience and sanity, I think it's combination of these.
Markup sans target
Foo
Bar
JS
// If `http` protocol present, assume external link
$('a[href^="http://"]').attr({'target':'_blank'});
// Otherwise, assume internal link
$('a:not([href^="http://"])').attr({'target':'_self'});
Worth noting that the above selectors do required jQuery proper.

Resources