AngularJS $routeProvider, fallback to default link navigation - angularjs

So not 100% of my site is "powered by AngularJS" some of it is just simple static HTML like a landing page or content oriented stuff, which is simple HTML for obvious reasons.
The only way I can seem to get a link to navigate normally is like this:
$routeProvider
.when('/plans', {templateUrl: '<%= asset_path('ng/views/start.html') %>'})
# Catch all
.otherwise({ redirectTo: (p,loc) -> window.location = loc })
It feels like the catch all should be simpler like I could do .otherwise(false) and it would just navigate normally. Same goes for `.when('/something'/, false) but I don't see anything in the docs that suggests this is possible.
Does anyone know of a better way to do this?
Edit 1:
One solution I've found is to use target='_self' in the link.
The other is apparently to set the "base url" of the application as outlined in the docs. Then any links outside of that base should navigate normally. However that doesn't seem to work as outlined and the example doesn't match what the documentation is suggesting either.

just creating a link to it external file
if you are using hashbang urls (e.g. #/plans) then you should be all set, if you are using html5 history api ($locationProvider.html5(true)) then you need to namespace your app (set base[href] properly) and put the content outside of that namespace.
relevant code:
https://github.com/angular/angular.js/blob/4df45b20d460239a0f5001fb0dd59f95e2d0e80d/src/ng/location.js#L560
Another solution is to use target="_self" on that a element. Again this should be an issue only when html5 (history pushState) is being used.

Related

How to clear ui-router hash on page change?

I'm using ui-router 1.0b3 with angular 1.5.x. Also using html5Mode(true). The hash's are not being used for the paths, they are just for the specific page it goes to.
I want to be able to go to
http://example.com/app/page#tab3
route name: app.page
Then navigate to another page, say route name: app.another, it will take me to the page, but the # stays. I don't want the # state to follow the navigation. Both pages need the same "app" parent. If I go to another it should not go to "http://example.com/app/another#tab3" which is what is is doing.
It did not do this on ui-router 0.3.1
I tried removing the hash during the transition:
$transitions.onBefore({exiting: 'app.**'}, function(trans) {
trans.params("to")["#"] = null;
$location.hash("");
});
but that doesn't work at all.
Help? I think this might be a bug, but I can't figure out a fix.
https://github.com/angular-ui/ui-router/issues/3245
I have the same problem. I found solution to the problem of ui-router developers.
You can clear out the hash by clearing out the parameter (parameter named '#').
In templates:
<a ui-sref="app.tasks({'#': null})">text</a>
In javascript code:
$state.go('app.tasks', {'#': null});
P.S. I use angular-ui-router, version is 1.0.0-beta.3
More information here:
https://github.com/angular-ui/ui-router/issues/3017

angularjs v1.3.15 deep linking / routing / path no longer working with hashtag (Migrated from v1.2.3)

I am very new to angular and working on some code that I wanted to upgrade the angular version from 1.2.3 to 1.3.15 (which I have also never done before). When I did, the navigation links on my index page stopped working; rather it seems like the router.js falls through to my $routeProvider.otherwise case and redirects to /home (you can see the refresh in my jumbotron). However, I also notice that when I click on the links, my url goes from localhost:8888/home to localhost:8888/home# or localhost:8888/home#home or localhost:8888/home#info, but the page routes don't work (the home page gets refreshed instead) - like the route is just appended to /home and it doesn't know what to do.
When I remove the deep linking ( hash / pound / # ) from the links in index.html, the code appears to work again, but I don't really understand why. It's highly likely I'm misunderstanding something in the breaking changes from 1.2 to 1.3, but the documentation made it seem like using # is still supported in 1.3.
By "upgrading" I replaced my angular.js, angular-resource.js, and angular-route.js in my project with their newer versions. I am using Apache karaf, and tested in both Chrome and Firefox with the same results.
Shortened code below:
Here is the index.html code that works in 1.2.3 and breaks in 1.3.15 (I used both # and #home to test if there would be a difference):
<div class="navbar navbar-inverse navbar-fixed-top">
...
My Project<small></small>
...
<div class="collapse navbar-collapse navHeaderCollapse" data-ng-controller="NavController">
<ul class="nav navbar-nav navbar-right">
<li class="{{navData['Home'].css}}">Home</li>
<li class="{{navData['Info'].css}}">Info</li>
</ul>
</div>
</div>
</div>
My router.js looks like:
angular.module("app").config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider.when('/home', {
templateUrl: "home.html",
controller: "HomeController",
isPublic: false
});
$routeProvider.when('/info', {
templateUrl: "info.html",
controller: "InfoController",
isPublic: false
});
$routeProvider.otherwise({ redirectTo: '/home' });
});
With 1.3.15, when I replace the hash / pound / # signs in index.html, with "/" for Home and "info" instead of the "#info", everything seems to work again.
I also tried upgrading potential dependencies to the following:
ui-bootstrap-tpls-0.13.0.js (was 0.6.0)
jquery-2.1.4.js (was 2.0.3)
I am using:
bootstrap.js (using 3.0.0)
I also have some additional libraries but didn't know if they are relevant to this. Let me know if I should add them to the list.
I attempted to simulate what I am seeing in plunker here: Angularjs v1.3.15 test # redirect
But the links appear to be working with the exception of when you click a link with just "#" as the href, the page template isn't loaded at all. So I don't know if the issue is related or completely different.
A few suggestions I've looked into (but maybe missed something):
I did see that people are upgrading ui-router, but I'm not currently using it; should I be? (Though plunker seems to be working with angular-route.js)
html5 is not playing nice in all arenas, but it appears configured in my code?
fixing the server to allow #, which I think is already done since the code used to work correctly
Thanks in advance for the help! If you could point me in the right direction that would also be appreciated!
The hash has a specific meaning in the HTML specification. It targets an element on a page. If you are on the page localhost:8888/home and click on the link localhost:8888/home#info the browser would jump to the element with the id info, if there was one. Consequently nothing happens if the element doesn't exist.
Angular intercepts clicks and url changes and allow you to change routes instead. To avoid any confusion (or unintentional behavior) Angular has two conventions. The first is using a prefix. It's optional and the one suggested is !. That's why this mode is also called the Hashbang mode, links to routes would start with #!.
The second, and more important one, is that routes start with /. So it's href="#/" and href="#/info". And this works no matter what version of Angular you are using. Of course, this fixes your plunker.
If you want to use hashes then don't activate the HTML5 mode.
One remark about your last point: The server doesn't care about #, since it only concerns the client.

Routing to a complete new template in AngularJS

I've learning this new tool since some days ago and know I'm beggining to have my own doubts.
I have an index.html, which holds almost all my app like so:
<html>
<head>
.
.
.
<body>
<div ng-include="'header.html'"></div>
<div ui-view></div>
.
<!-- Loads all the scripts and other stuff-->
</body>
Ok, in the website I'm building, I have some sections that share the header, that's why I include it. Nonetheless, there is another section where is completely different from the others, hence, I don't need to include the header.
Now, the question is: How can I route to this completely new section ? Because the index loads the other views in the below the header. All I can think about right now is creating another index.html-like page, loading all the scripts and everything again. I think there should be a more elegant solution in Angular.
I'm using angular-ui-router for the routing.
Can you please give me a hand? Thanks
Use nested states, put this in your app's state configuration.
$stateProvider.
$state('stateWithHeader', {
template: '<header></header><div ui-view></div>',
controller: 'HeaderStateController'
}
.$state('stateWithHeader.subState', {
template: '<div>Content!</div>',
controller: 'HaderSubStateController'
}
.$state('stateWithoutHeader', {
template: '<div>Yeah, no header!</div>',
controller: 'HeaderStateController'
};
Make sure to read the docs, they're super informative and clear on most subjects.
What #Claies said above will absolutely work. Here's an example from my own site at http://PaperQuik.com.
I have multiple routes which correspond to different templates. Each one just does the following to get the same menu header at the top of the page:
<div ng-include="'views/menu.html'"></div>
If I needed a different top I could use a different include. You can see the source to my various templates here: https://github.com/JohnMunsch/PaperQuik/tree/master/app/views
Note: My example is just using the old ngRouter (not the new one which is expected for AngularJS 1.4) and thus it is way less sophisticated than what you can do with either the new ngRouter or the AngularUI Router you're using. Still, you can see how easy it is even with that super simple router.

Linking to external URL with different domain from within an angularJS partial

All I am trying to do is include an anchor tag inside the html of a partial that links to an external site. Were this standard html, the code would simply be:
google
As simple as this is, I cannot seem to find a working solution for getting past angular intercepting the route (or perhaps replacing my anchor with the https://docs.angularjs.org/api/ng/directive/a directive unintentionally?).
I have scoured SO and the rest of the web and seen a myriad of solutions for dealing with: links within the same domain, routing within the SPA, routing within a page (ala $anchorScroll) but none of these are my issue exactly.
I suspect it may having something to do with using $sce but I am an Angular n00b and not really sure how to properly use that service. I tried the following in my view controller:
$scope.trustUrl = function(url) {
return $sce.trustAsResourceUrl(url);
}
with the corresponding:
<a ng-href="{{ trustUrl(item) }}">Click me!</a>
(as described here: Binding external URL in angularjs template)
but that did not seem to do the trick (I ended up with just href="{{" in the rendered page).
Using a plain vanilla anchor link like this:
google
also failed to do the trick (even though some online advised that standard href would cause a complete page reload in angular: AngularJS - How can I do a redirect with a full page load?).
I also tried adding the target=_self" attribute but that seemed to have no effect either.
Do I need to write a custom directive as described here?
Conditionally add target="_blank" to links with Angular JS
This all seems way too complicated for such a simple action and I feel like I am missing something obvious in my n00bishness, at least I hope so because this process is feeling very onerous just to link to another url.
Thanks in advance for any solutions, advice, refs or direction.
It turns out that I did in fact have all anchor links in the page bound to an event listener and being overridden. Since that code was fundamental to the way the page worked I did not want to mess with it. Instead I bypassed it by using ng-click to call the new url as follows:
HTML:
<a class="navLinkHcp" href="{{hcpurl}}" title="Habitat Conservation Plan" target="_blank" ng-click="linkModelFunc(hcpurl)">Habitat Conservation Plan</a>
Controller:
$scope.hcpurl = 'http://eahcp.org/index.php/about_eahcp/covered_species';
$scope.linkModelFunc = function (url){
console.log('link model function');
$window.open(url);
}
And voila! Good to go.
Thanks again to KevinB for cluing me in that this was probably the issue.

How to redirect in AngularJS without rendering template

I'm trying to redirect to an external page from my AngularJS file if the user enter a special url, for instance /test. I have gotten this to work in multiple different ways but all the different ways show a "flash" of the design from index.html. I would like it to go direct without rendering any html at all!
Here is a fiddle of one of the examples, but it is not the best place to test since I cant redirect from jsiffle.net :-)
$routeProvider.when("/test", {
resolve: {
controller: "Redirect"
}
});
Also had one example where I just used a controller and a empty template in the routing, but it gave me the same result.
Any ideas?
If you know the URL(routing) then use,
$location.path('the_URL');

Resources