AngularJS and PhoneGap: $location.path causes subsequent tempateUrl lookup to fail - angularjs

I'm having trouble getting path lookup to work with a AngularJS v1.2.0 and PhoneGap/Cordova Android application. I've come pretty far with html5mode(true) by setting <base href="."/> in index.html and then changing $routeProvider.when('/') to $routeProvider.when('/android_asset/www/index.html'). After that I am able to get redirectTo('login') to reach $routeProvider.when('/login') and there render templateUrl: 'static/partials/login.html' as expected.
The problem I have is that if I instead try to redirect to the login page from my Javascript code with $location.path('/login');, the route is found but templateUrl loading fails with an insecurl exception.
I've tried whitelisting access to file:// by using the new angular-sanitize module, but that does not help.
How can I make $location.path() do the same things as redirectTo so that the partial is loaded? Or is there some other way to solve this problem?
UPDATE: I got a bit forward by adding a call to replace() after the path function, e.g.:
$location.path('/login').replace();
but that seems like a hack, and it still causes the templateUrl in the otherwise route to fail with the same exception.
Any ideas on what might be wrong? Is it that html5mode(true) just does not work at this moment with Phonegap and the only way to fix this is to set it to false and add hashtags to every path (like is done in the angular phonegap seed project)?

For future reference, this is how I managed to solve the problem:
AngularJS currently does not seem to support html5mode(true) inside a Cordova application because of the insecurl problem I reported. What I had to do is add
var h5m = (typeof html5Mode !== 'undefined') ? html5Mode : true;
$locationProvider.html5Mode(h5m);
which gives me the possibility to explicitly set html5Mode in the PhoneGap index.html with a global variable:
<script>
var html5Mode = false;
</script>
So now $location.path('/login') as well as redirectTo: 'login' works, but links in html files, don't. To get those working in PhoneGap, with html5Mode disabled, I had to add #/ in front of every link, e.g. login.
That makes PhoneGap work, but breaks the web page which uses History API with html5Mode(true). The last piece of the puzzle was to add <base href="/"/> to the web page's index.html (and leave it out of the index.html of the PhoneGap project.) So now even though I have a link that says #/login in the web page, I get to the url http://example.com/login and don't see any hashes in the address bar.
**
So in the end I have History API working in my web page and History API disabled in the PhoneGap project (where there really is no need for History API as there is no address bar). The only downside is the extra #/ I have to put in each template html file, but that is a minor annoyance compared to the ability to use all of the same html and javascript files for both web and mobile.

I had this same problem as well. I managed to fix it by skipping the leading slash in the route config:
$routeProvider
// route for the foo page
.when('/foo', {
templateUrl: 'foo.html', //previously: '/foo.html'
controller: 'fooController'
}) //etc.

Related

angular otherwise not working with spring boot

I am facing some weird type of behavior with spring boot + angular js while doing routing. Although routing is working but otherwise redirect to is not working.
For example:
if the url is http://localhost/admin/home#/analysis(working)
if the url is http://localhost/admin/home#/ (working)
but if the url is http://localhost/admin/home (not working)
I have configured otherwise but its not doing any benefit
Below is my code:
.config(['$routeProvider','$httpProvider',function ($routeProvider, $httpProvider) {
$routeProvider.when('/analysis', {
templateUrl : '../resources/views/includes/dashboard.html',
controller : "RegistrationController"
}).when('/', {
templateUrl : '../resources/views/includes/profile.html',
controller : "RegistrationController"
})
.otherwise({
redirectTo: '/'
});
$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
}]);
I have placed in html
I would suggest you to take a look at $locationProvider.html5Mode(true).
It tells angularJS to use HTML5 strategy if available. Basically # is required for those browsers who do not support HTML5.
Also, you will be required to configure <base> tag of html.
Even when you will implement these concepts, you will stumble across another issue which I faced as well. If you navigate via href in the application, it would work , but if you copy the url and paste it directly in the browser, you'll get error as it would directly hit the server and will try to find necessary URL mapping on the server.
For more details, you can look at this this question which I asked for this issue
I hope it'll help.
Your problem is more related to SEO-related AngularJS implementation, basically, the solution to this is using the rewrite functionality of Apache or Nginx.
For more information, you can start here.

Angular Hash versus Hashbang

Why does Angular sometimes use a hash in the URL and other times use a hashbang? I've started writing two Angular apps from scratch. Neither are using HTML5 mode. Both have the same default route. However, the default URLs display differently.
I've been seeing this random behaviour for at least a year... long before angular-route v1.6. Also, I've always used angular-ui-router.
The default route:
configRoutes.$inject = ['$urlRouterProvider'];
function configRoutes ($urlRouterProvider) {
$urlRouterProvider.otherwise('/');
}
App #1 resolves this...
http://localhost:3000
... to this ...
http://localhost:3000/#/
App #2 resolves this...
http://localhost:3001
... to this ...
http://localhost:3001/#!/
Note the last two characters in the default URL.
I know how to activate HTML5 mode and pretty URLs. That is not what I'm asking. I would really like to understand the significance of both URLs above and why Angular is writing them differently.
Current versions:
angular-ui-router v0.3.2
angular v1.6.0
When we upgraded from angular 1.5 to angular 1.6, the URL of our app changed from /#/ to /#!/. We fixed the problem by configuring the hashPrefix in the application config:
angular.module("myApp").config(function($locationProvider) {
$locationProvider.hashPrefix("");
});

AngularJS "#!" on url

someone knows what "#!" Means. on the url?
I was working until then this appears,I had a "#" always in the url and would like to keep it that way.
Currently routing is not working anymore,probably because of this url change.
It's part of a business project, i don`t want to change to html5Mode.
I tried to use:
$locationProvider.hashPrefix("");
Even correcting the url in this way routing is having problems
Thats called hash-bang.
To fix this use :
angular.module('yourApp', [])
.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix('');
}]);
Adding html5Mode would even get rid of the '#' in the url but if you refresh the page, then you would get a 404 error. This can be fixed by configuring your server a bit. For that you might want to check the nice little tutorials :
https://scotch.io/tutorials/pretty-urls-in-angularjs-removing-the-hashtag
https://www.theodo.fr/blog/2017/01/pretty-url-in-angularjs-and-loopback-drop-the/
There is another answer to the hashbang issue in stackoverlow :
Doing links like Twitter, Hash-Bang #! URL's
You can use html5Mode in your location provider.
$locationProvider.html5Mode(true);
more info https://scotch.io/tutorials/pretty-urls-in-angularjs-removing-the-hashtag
Set html5mode true in your app.config
$locationProvider.html5Mode(true).hashPrefix('*');

AngularJS Routing not working when url typed

So, I'm pretty new to AngularJS and I'm trying to use AngularJs ngRoute in my application.
It all works smoothly when I start at the application homepage:
http://localhost:8080/appName/
And when I click on links from this point it works smoothly.
However, when I type a URL that I know exists/works, it gives me a 404 error. If I go to that link by using the application instead of the url it loads fine, even though it has the same url.
Eg. http://localhost:8080/appName/search
will give a 404, even though that is the same url that is the default redirect.
Indeed, the only url that will load by typing in the location is the base URL I mentioned above.
My app.js looks like this:
app.config( ['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider){
$routeProvider
.when("/search", {
templateUrl: "search.html",
controller: "SearchController"
})
.when("/results", {
templateUrl: "results.html",
controller: "ResultsController"
})
.when("/browse", {
templateUrl: "browse.html",
controller: "BrowseController"
})
.otherwise({redirectTo:"/search"});
//This gets rid of the # on the urls to the templates
$locationProvider.html5Mode(true);
}]);
I am hosting this on a glassfish4 server.
Is there something obvious I am missing/misunderstanding about how ngRoute works? Is there some setting that I am missing?
All help appreciated...
EDIT 1: As #Matthew Green below says, I need to configure the webserver to return the index.html for all pages below
http://localhost:8080/appName
I know I am being completely dense here, but where abouts is this configured? I am hosting the code in a MAVEN Jersey-Quickstart-Webapp.
When you use ngRoute, you are using javascript to handle routing to create a SPA. That means you need to hit a real page that loads your routing for your application to know what page to route to.
For example, your http://localhost:8080/appName/ should be routing to your index.html which would contain the javascript for your routing. With that page loaded it knows how to handle the links you have in your application. However, if you were to go directly to http://localhost:8080/appName/pageName you also need that to load index.html, as it is the one that loads your routing. Once your routing is loaded it should direct you to the correct page in your application. Without redirecting in place, http://localhost:8080/appName/pageName is not a real page and therefore correctly returns a 404.
Knowing this, the thing you have to figure out is what kind of server setup you have to configure the appropriate redirects for everything under http://localhost:8080/appName/ to go to your index.html page.

AngularJS routing with Mongoose webserver

I'm testing a website locally on my machine. It uses AngularJS for routing and page changes, and I'm attempting to test the routes using the Mongoose webserver (extremely light).
My code is as follows:
app.config(['$locationProvider', '$routeProvider', function ($locationProvider, $routeProvider) {
$locationProvider.html5Mode(true);
$routeProvider.when('/who', {templateUrl: '/js/partials/who', controller: 'whoPage'});
$routeProvider.when('/what', {templateUrl: 'partials/what'});
$routeProvider.when('/want', {templateUrl: 'partials/want'});
$routeProvider.otherwise({ redirectTo: '/' });
}]);
(I haven't set up controllers for some of the other pages yet. I've been testing the "who" page.)
I'm running the page from localhost:8080. In my application, when I click a link to change the location, nothing happens. The URL changes to "localhost:8080/who", but I get no messages from console, and I get no changes on my page. However, if I then refresh that URL, I get a 404 error.
I don't have any server-side routing set up. Is this a necessity for Angular apps? Is there something wrong with the code I've written, or should I try a different test webserver?
$locationProvider.html5Mode(true);
will make angular use "push state" from the HTML5 History API.
This means that you'll see the url change in the location bar, but that won't cause the browser to actually reload your page. When you reload the page, the browser will now fetch that url from the webserver, which doesn't have it.
A common trick is to use URL rewrites to map any url back to index.html. You should take care of not remapping the urls that point to static files such as your javascript and css resources. That's usually easy because it's a good practice to group all your css and js files in some directory instead of scattering them in the top level dir.
You can read about how to configure mongoose URL rewrites at https://www.cesanta.com/developer/binary#_url_rewrites

Resources