I have been beating my head against the wall trying to figure out why angularJS routing won't work in phonegap for me. I have all the files setup correctly and i don't receive any errors. I'm trying to change the url using the $location.url service directly from angular. So when you tap on a div the controller will have $location.url("profile") for example and nothing will happen. I tried the solution found in this stackoverflow but that's not working for me. Am I doing something wrong, or is there a better way to be approaching this? Following is the routing I have setup
var app = angular.module("App", ["hmTouchevents"])
.config(function($routeProvider) {
$routeProvider
.when("/index.html", {
templateUrl: "/views/login.html",
controller: "loginCtlr"
})
.when("/landing", {
templateUrl: "/views/landing.html",
controller: "landingCtlr"
})
.when("/single-view/:id", {
templateUrl: "/views/single-view.html",
controller: "singleViewCtlr"
})
.when("/restaurant", {
templateUrl: "/views/restaurant-info.html",
controller: "restaurantCtlr"
})
.when("/profile/:id", {
templateUrl: "/views/profile.html",
controller: "profileCtlr"
})
.when("/lists/:list", {
templateUrl: "/views/lists.html",
controller: "listsCtlr"
})
.when("/follow/:type", {
templateUrl: "/views/follow.html",
controller: "followCtlr"
});
});
A sample controller would be:
app.controller("listsCtlr", ["$scope", "$location", function($scope, $location){
$scope.goTo("profile");
}]);
As always any help is much appreciated.
I had a problem similar to this tonight. The core issue here is that PhoneGap doesn't have a web server built in. If you're developing locally, you probably are using a web server, so you can do something like: http://localhost/#/profile and the routing will work.
However, PhoneGap loads your code with a file:// URL, not http://. If you do $location.url("profile") you're replacing the entire URL with just file://profile, which doesn't exist. Same thing if you use a link like this: My Profile
The solution is to somehow get your links to point to the right place. If you're using $location.url() you can prefix it with your file path: $location.url( window.location + "#/profile" )
If you're just making a link, you should be able to get away with taking off the leading slash to make it a relative URL: My Profile becomes My Profile
Had the exact same issue... I was able to fix this easily by adding the following code to the head of my index.html file.
<base href="/android_asset/www/" />
Hope this helps.
in your controller try...
$location.path('/profile');
After much tinkering, here's what worked for me!
If you can use $location.path() within the controller, it should work as expected, but if you need to use href-style links, you can build the links off the angular "base" page (e.g. main.html):
Link To Profile
Related
I am facing a number of troubles related to AngularJs routing. I have already tried to find answers online but I still am not very clear with the solutions provided.
First of all, here is my routing block:
var myApp = angular.module('myApp', ["ngRoute", "ngAnimate"]);
myApp.config(function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when("/", {
templateUrl: "../view/home.html",
controller: "slideShowController",
})
.when("/business&consumer", {
templateUrl: "../view/govnservices.html",
controller: "productController",
})
.when("/about", {
templateUrl: "../view/about.html",
controller: "pagController",
})
.when("/project", {
templateUrl: "../view/projects.html",
controller: "projController",
})
.when("/service", {
templateUrl: "../view/services.html",
controller: "servController",
})
.otherwise({
redirectTo: '/',
})
});
And this is how I am passing the reference to my links:
Home
Another link:
name: "About Us",
templateUrl: "/about",
Now everywhere it is specified as:
Home
But on using '#' my links are not working (still don't know why.)
Again on not using '#' all my links are working but if I try to reload my page then it gives a 404 error:page not found.
Someone please help me out with this and please mention in comment if any part is not clear. Also please mention any good source to learn routing.
Your question is not entirely clear where you state: "Again on not using '#' all my links are working but if I try to reload my page then it gives a 404 error:page not found."
So are you using the # or not? Since we are talking html5mode I will assume not for now (Because you have to not use it in that mode)...
So I assume the symptom your seeing is that you
Navigate to "http://wheremyappishosted/" This loads your app and
everything is fine...
Now you click "About", This changes your
location to "http://wheremyappishosted/about" and again everything
works just fine.
Now you hit Refresh in your browser and suddenly
you get a 404
Sounds about right? If so... The problem is your server and not the AngularJS routing...
This is what happens from the servers perspective:
A request for "http://wheremyappishosted/" is received, the server responds
with the main page for the app. Everything is fine...
AngularJS handles the route change, the server does not receive any requests
for "http://wheremyappishosted/about" It DOES however receive a request for
the template "../view/about.html" which it can find and responds with.
Everything is fine...
A request for "http://wheremyappishosted/about" is received, but the server
does not know what to respond for that so it gives a 404...
The solution is that you need your to deliver your main page as a fallback route... You may wan't to have certain filters in place so that a unknown route under the parent route "api" may still fail with a 404 etc...
But the essence of it is that the server doesn't know what to respond with for "http://wheremyappishosted/about", so you need to configure it so it knows that.
I'm using $stateProvider to handle my routes in Angular 1 and I'm confused as to why my routes have an /# before they all start. I wouldn't mind but when I test those routes in Postman the routes return a 404 error. I'd like to find out why /# that gets added for my routes and get rid of it so I can connect my front end to my backend in node. I'm kind of new to using angular with node this so I'm not sure if I'm explaining my problem correctly.
Here's my code
app.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise("/main");
$stateProvider
.state("main", { url: "/main", templateUrl: "templates/main/main.view.html", controller: "MainCtrl" })
.state("map", { url: "/map", templateUrl: "templates/map/map.view.html", controller: "MapCtrl" })
});
These are what my routes look like
http://localhost:8080/#/main
http://localhost:8080/#/map
but I want them to look like
http://localhost:8080/main
http://localhost:8080/map
To get rid of #/ you would have to set $locationProvider.html5Mode(true); in one of your config files.
angular.module('app', []).config(function ($locationProvider) {
$locationProvider.html5Mode(true);
});
For more information on html5 mode vs hashbang mode, have a look at the official angular documentation
Keep one thing in mind though, in html5 mode, your app might not be able to handle page refreshes properly without some server side url re-routing. More information in one of the stack overflow posts here: Reloading the page gives wrong GET request with AngularJS HTML5 mode
Man, just follow advises here and it's gonna be alright. Removing the fragment identifier from AngularJS urls (# symbol).
And one more usefull link https://docs.angularjs.org/guide/$location.
So I am having an issue in setting up my angular routes.
Moving straight to the point, my angular routes defined don't hit my mvc controller and thus action methods.
The action method return partial views, which represent my templates.
Here is an image of my route configuration.
Here is an image of my controller actions.
I am sure I am missing something, but can't seem to figure out what.
This example helps you to understand better about $routeProvider and $locationProvider.
The only issue I see are relative links and templates not being properly loaded because of this.
from the docs regarding HTML5 mode
Be sure to check all relative links, images, scripts etc. You must either specify the url base in the head of your main html file () or you must use absolute urls (starting with /) everywhere because relative urls will be resolved to absolute urls using the initial absolute url of the document, which is often different from the root of the application.
In your case you can add a forward slash / in href attributes ($location.path does this automatically) and also to templateUrl when configuring routes. This avoids routes like example.com/tags/another and makes sure templates load properly.
Here's an example that works:
<div>
Home |
another |
tags/1
</div>
<div ng-view></div>
And
app.config(function($locationProvider, $routeProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
templateUrl: '/partials/template1.html',
controller: 'ctrl1'
})
.when('/tags/:tagId', {
templateUrl: '/partials/template2.html',
controller: 'ctrl2'
})
.when('/another', {
templateUrl: '/partials/template1.html',
controller: 'ctrl1'
})
.otherwise({ redirectTo: '/' });
});
If using Chrome you will need to run this from a server.
Well what worked for me was to remove the setting for the $locationProvider.html5Mode. As someone mentioned in another stack overflow post, here MVC5 and Angular.js routing - URLs not matching using the locationProvider in MVC seems to screw up the routing. I am still to investigate why exactly this happens, as all I thought it did was remove the '#' in the url, but seems like there's more to it
I am having issue with routing on mobile phone when I use phonegap.
Routing on browser works but on mobile devices is not working.
If there is any question, I can provide more code.
route.js:
app.config(['$routeProvider','$locationProvider','$compileProvider', function($routeProvider,$locationProvider,$compileProvider) {
$routeProvider
.when('/', {
templateUrl: '../login.html',
controller: 'loginController'
})
.when('/home',{
templateUrl:'../home.html',
controller:'homeController'
})
.when('/profile', {
templateUrl:'../myprofile.html',
controller:'profileController'
})
.when('/reservations',{
templateUrl:'../reservations.html',
controller:'reservationController'
})
.when('/ordernow',{
templateUrl:'../ordernow.html',
controller:'ordercontroller'
})
.otherwise({
redirectTo: "/home"
});
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension):/);
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension):/);
}]);
After few hours of struggling:
solution: remove "../" from templateUrl
I guess this particular issue might have been fixed long ago, but I was having similar trouble with angular 1.6 and cordova android app.
I was using the correct path for templateUrl but still routing was not working.
After spending a whole day looking through different documentations and trying out different things i stumbled upon a small mystery. I was debugging the cordova app using google chrome inspect and found the app URL to be
file:///android_asset/www/index.html#!/
When i navigate to another page, I get the URL
file:///android_asset/www/index.html#!/#%2faccounts
Then while investigating that, I stumbled upon this
I used the following while configuring the router
$locationProvider.hashPrefix('');
This seemed to fix the problem for me. Code snippet below:
var prakriya = angular.module("prakriya",["ngRoute"]);
prakriya.config(function($routeProvider, $locationProvider){
$locationProvider.hashPrefix(''); //Added Line here
$routeProvider
.when("/", {
templateUrl: "templates/workspace.html",
controller: "workspace"
});
});
I trying to make an application that contains multiple views as template. The templates are under the js/app/pages/ folder. And I have 2 templates to show and route. My routing section is:
var app = angular.module("myApp", ['ngRoute', 'ngMaterial']);
app.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/Page', {
templateUrl: 'js/app/pages/Page.html',
controller: 'pageController',
reloadOnSearch: false
})
.when('/Settings', {
templateUrl: 'js/app/pages/Settings.html',
controller: 'settingsController',
reloadOnSearch: false
})
.when('/Admin', {
templateUrl: 'js/app/pages/Admin.html',
controller: 'adminController',
reloadOnSearch: false
})
.otherwise({
redirectTo: '/Page'
});
$locationProvider.html5Mode(true);
});
And my html file contains
<div id="menu"></div>
<div ng-view></div>
Menu div contains menu elements that route me between the pages. For example, when I run this site on browser, URL will be localhost/Page, and when I click the settings button URL change with localhost/Settings. But when I press the F5 button in my keyboard. Page gives me error The resource cannot be found..
I search on the internet "how to refresh routing page in angularjs" and find some solutions but I couldn't make them work for me. I tried $route.reload() and $routeUpdate() method but that does not work for me. Maybe I'm wrong in something.
If you are using Apache server this should work run this in terminal
sudo a2enmod rewrite && sudo service apache2 restart
works for me
Solved! I couldn't manage refresh with ngRoute. Then i convert it into ui-router. I declare the states by urls. And the refresh is working. Thanks for comments and answers. Maybe this will help someone.
Actually when you are pressing F5 from keyboard, it is hitting to your server for that page, not angular because you don't have any # sign between your URL. For angular, URL should be like as - localhost/#/Page
Use html5mode
A great article about it here
to init its very simple
.config(function($routeProvider, $locationProvider) {
// other routes here
$locationProvider.html5Mode(true);
});
When you "reload a page", you whole app will reinit again. That means if you are not on the main page, and the sub route you are at missing some data, you will likely get an error.
You should look into resolve attribute for routes, so for example,
.when('/Settings', {
templateUrl: 'js/app/pages/Settings.html',
controller: 'settingsController',
reloadOnSearch: false,
resolve: {
resourceone: function(){return whatsneeedtoberesolvehere;}
}
})
that way no matter where your app is reloaded, it will have the necessary data to boot the page
Just keep the # in URL, you don't have to put extra effort to manage reloads etc. you can think a "#" in URL represent a specific state in single page application.
Otherwise it can be managed by module rewriting, that map the url with hashed version URL internally for AngularJs app.