AngularJS routing without the hash '#' - cannot get it work - javascript

I have read this post many times, and I have followed the instructions there, but I cannot get this to work.
AngularJS routing without the hash '#'
I have a Qt app that sends a request to a URL with a # in it. That URL is routed to the Angular code. I want to change this to not require the #.
This is my Angular code:
angular.module('app').config(function($routeProvider, $locationProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'home.html',
controller : 'home'
})
// route for the workitem page
.when('/workitem/:identifier', {
templateUrl : 'workitem.html',
controller : 'workitem'
});
$locationProvider.html5Mode(true);
});
This is my nginx config:
server {
listen 8000;
server_name foo.bar.com;
location / {
include /usr/local/nginx/conf/mime.types;
root /projects/larry/web;
}
}
In /projects/larry/web there is an index.html, which loads the JS module with the $routeProvider.
When I go to the URL: http://foo.bar.com:8000/#/workitem/12345 this works fine. The JS is loaded, and the $routeProvider gets the URL and does what it's supposed to do.
But if I omit the # and go to http://foo.bar.com:8000/workitem/12345 then the JS code is not loaded and the request fails.
How can I make this work without the hash?

You also need to add the <base href="/" /> in the <head> of your html page.
Example below.
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>My Website</title>
<base href="/" />
</head>
<body>
</body>
</html>
EDIT
This will take you to a GitHub post with the answer. https://gist.github.com/cjus/b46a243ba610661a7efb

Related

Site pages not scrollable after adding angularjs

I have a site that was downloaded first as a template. in order to convert into an angular app, i removed all the <head>, <html> and <body> tags of all other pages except the index page which contains the <ng-view>. now the routing is working just fine to redirect to all the pages but the problem is that the pages are not scrolling anymore. the index.html page looks like this
<!DOCTYPE html>
<html lang="en" ng-app="myApp" ng-controller="IndexController">
<head>
<title>My site</title>
</head>
<body>
<div ng-view [onload="string"]
[autoscroll="string"]></div>
</body>
</html>
and the other pages look something like this
<div>
<!-- page content goes here-->
</div>
app config is like
var app = angular.module('myApp',['ngRoute','LocalStorageModule','ngStorage']);
app.config(
function($routeProvider)
{
$routeProvider
.when("/", {templateUrl : "home.html", controller: 'HomeController' })
//other routes
});
when i run this site, all the pages that have long content are cut short and cannot scroll to view the rest of the content. please help. I have been working with angularjs for some time now but i have never come across anything like this before.

How to setup AngularJS $locationProvider HTML5 mode for non-root base urls?

I have a working AngularJS (1.3.8) application, which is deployed as a web app in Tomcat under an application context 'app'.
URLs look like this:
https://www.myserver.com/app/#/login
https://www.myserver.com/app/#/register
etc. Routes are defined like this:
$routeProvider.when(
'login',
{templateUrl: 'partials/login.html?' + now, controller: 'LoginController'}
);
$routeProvider.when(
'register',
{templateUrl: 'partials/register.html?' + now, controller: 'RegistrationController'}
);
$routeProvider.otherwise(
{redirectTo: 'login'}
);
Everything is working fine. What I now need to do is remove the hashbangs from the URLs and use the HTML5 mode of $location. So far, I can not get this to work.
My assumption was that I just need to call
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
and now the app URLs change to
https://www.myserver.com/app/login
https://www.myserver.com/app/register
This is not working. When I request the URL
https://www.myserver.com/app
Angular redirects to
https://www.myserver.com/login
Overall, the whole routing and resource loading is broken with this change. For example, the partials URLs in the routing definitions can not be resolved. They are only working when I add a '/app/' prefix.
I tried to use the base tag, changing the $locationProvider call to
$locationProvider.html5Mode({
enabled: true
});
and using
<base href="/app">
Surprisingly, this has no effect. Still, entering https://www.myserver.com/app leads to a AngularJS-redirect to https://www.myserver.com/login. The URL https://www.myserver.com/app/login is not available.
This is how I use the base tag:
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<link href="css/mycss" rel="stylesheet" type="text/css">
...
<script src="js/my.js"></script>
<base href="/app">
</head>
<body class="ng-cloak">
<ng-view></ng-view>
</body>
</html>
I also encounterd other problems. For example, if I change the location of the base tag inside the HTML file like this:
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<base href="/app">
<link href="css/mycss" rel="stylesheet" type="text/css">
...
<script src="js/my.js"></script>
</head>
<body class="ng-cloak">
<ng-view></ng-view>
</body>
</html>
then suddenly the JS and CSS files can not be resolved any more during load.
Can somebody explain what I am doing wrong?
I believe you must have trailing / inside base href
<base href="/app/">

Issue with direct URLS of Angular1.3 routing - even when html5mode is false

If I'm navigating through the links, I'm able to open the respective views but if I copy paste the entire url, view is not loading & no errors in console.
Here is my config of main app module,
.config(['$locationProvider', '$routeProvider', function ($locationProvider, $routeProvider) {
$routeProvider
.when('/welcome', {
templateUrl: 'src/app/welcome/welcome.html'
})
.when('/terminology', {
controller: 'TermsController',
controllerAs: 'vm',
templateUrl: 'src/app/terminology/term-table.html'
})
.when('/', {
redirectTo: '/welcome'
})
.otherwise({
redirectTo: '/welcome'
});
$locationProvider.html5Mode(false);
}]);;
Eg:
1. If I click on home link, welcome view is loading in ng-view and the URL becomes (URL1) "http://localhost:8081/web/#/welcome"
If I click on terms link, terminology view is loading in ng-view & the URL becomes (URL2) "http://localhost:8081/web/#/terminology"
but If I copy paste the entire URL in a new tab, the view becomes blank. There is no error in the console. I'm using Angular1.3
ADDED:
Moreover, for the first time also default view is not loading...
Thanks in advance
I found the solution for this.
My actual index.html file is like this
<html class="no-js" lang="en" ng-app="app">
<head>
<!-- my css files -->
</head>
<body>
<!-- this shell page contains "ng-view" directive which is causing the whole problem -->
<div ng-include="'src/app/igl-layout/shell.html'"></div>
<!-- my js files -->
</body>
now I replaced the content of shell.html to the above ng-include directive(line), then everything works fine.
Can anyone tell me why this is happening?
If ng-view is inside shell page, its not working as expected but if it is in index.html page its working fine.

AngularJS infinite loop with ng-view

I've just started using AngularJS for a new app I'm looking at putting together but I've run into a problem when using routes and views.
I've stripped this example down to the bare minimum but the issue remains. All this example is doing is hitting the server and returning the index.html page, which then sources Angular etc.
index.html
<!doctype html>
<html lang="en" ng-app="main">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" src="css/style.css" />
<script type="text/javascript" src="js/ext/angular.min.js"></script>
<script type="text/javascript" src="js/ext/angular-route.min.js"></script>
<script type="text/javascript" src="js/main.js"></script>
<script type="text/javascript" src="js/test.js"></script>
<base href="/ui/">
</head>
<body>
<div ng-view></div>
</body>
</html>
main.js
(function() {
var app = angular.module('main', ['ngRoute', 'test']);
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when('/test', {
templateUrl: 'html/test.html',
controller: 'TestCtrl'
})
.otherwise({
redirectTo: '/test'
});
$locationProvider.html5Mode(true);
}]);
})();
test.js
(function() {
var app = angular.module('test', []);
// get hierarchy
app.controller('TestCtrl', ['$scope', function($scope) {
alert('here');
}]);
})();
test.html
<div>FooBar!</div>
The alert gets fired infinitely but I just don't know why. I've seen other examples where ng-view and routing appear to be used exactly the same way, so I'm not sure what I'm doing wrong...
I had same problem sometime ago. Please, use firebug or some network control in the same browser at the developers tools panel where you can see the requests to the server for resources and then check that test.html file is requested and is correctly retrieved. It seems like the only one that is retrieved is the index.html and due this, the loop.
Probably you have to use this templateUrl value "/html/test.html" with "/" before. To localize this resource.
This is the idea that I'm proposing you. Localize the test.html resource with the correct way. I hope this can help you.
I had this issue today in March 2016. I have just found out what was causing the infinite loop when ng-view is present in the html (index.html in my case which is the initial html loaded at the start).
Ok, the problem was after all very simple one. I had this route provider setting in my app.js
angular.module('myapp',['ngRoute'])
.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl:'/index.html',
controller:'MyAppCtrl'
})
Since the initial html loaded is index.html, and the url at that point is '/', and the routeProvider invokes the code at when '/'. Yes, it loads index.html again, and again and again and again... till it dies. The solution is not to set index.html as the templateUrl for the '/' route. The html (template) should not include <div ng-view></div>.
Here's how I've done it, example here
Code
.config(['$routeProvider', '$locationProvider',function($routeProvider, $locationProvider) {
$routeProvider
.when('/test', {
template: '<div>test</div>',
controller: 'testCtrl'
})
.when('/other', {
template: '<div>Delete</div>',
controller: 'otherCtrl'
})
.otherwise({
redirectTo: '/test'
});
$locationProvider.html5Mode(true);
}]);
Ok, I solved my problem. I've accepted sergio's as it was closest to how I realised what the problem was - my app was requesting the html file from the application server, which is set up to return the index.html file as a default action. As the html request had no associated action, the default response of returning index.html was kicking in instead of the test.html file.
Once I changed the url so it was getting the html file from the web server, everything worked great. If I'd taken a moment earlier to actually think through what was happening, it would've been obvious.
Thanks for the responses!

Angular JS: How to load js files in partials

Very new to AngularJS, I am guessing the term for what I am trying to do is lazy load. I have looked at several different blogs and I have not found a complete working solution that is purely using AngularJS.
I understand that if I put the <script src="js/process1.js"></script> in index.html, all works fine, I am trying to cut down on the amount of js that is pulled down on the initial load.
With the script tag sitting in the partial, it is never loaded so the P1Ctrl is never created. So currently, if a user go into the application and never goes to process55, the user still has the code there for process55 even though it was never used.
Is there a way to load the file and inject the objects created in the process1.js into the app defined in main, at the time process1 route is executed?
index.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Large Angular App</title>
<link rel="stylesheet" href="lib/foundation/css/foundation.min.css" />
</head>
<body ng-app="largeApp" ng-controller="LargeAppController">
<div>
Home | Process1
</div>
<br/>
<br/>
<br/>
<ng-view>Test</ng-view>
<script type="text/javascript" src="lib/jquery/jquery.min.js"></script>
<script type="text/javascript" src="lib/angular/angular.js"></script>
<script type="text/javascript" src="lib/angular/angular-route.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>
js/main.js:
var app = angular.module("largeApp", ['ngRoute']);
var appCtrl = app.controller("LargeAppController", function(){});
app.config(function ($routeProvider, $controllerProvider) {
// save references to the providers
app.registerCtrl = $controllerProvider.register,
$routeProvider.when('/', {templateUrl: 'partials/home.html'});
//Thinking I need to set up a resolve to fire off a script loader to load js.
$routeProvider.when('/process1', {templateUrl: 'partials/process1/process1.html'});
$routeProvider.otherwise({redirectTo: '/'});
});
partials/home.html:
<div>
Home Page
</div>
partials/process1.html:
<script type="text/javascript" src="js/process1/Process1Controller.js"></script>
Process 1 {{process1data}}
js/process1.js:
console.log("I made it here");
app.registerCtrl('Process1Controller',function($scope){
$scope.process1data = "Hello!";
}
]);
To implement lazy loading of controllers in simple way, you have to do the following:
Save $controllerProvider.register (which is the only method to add a controller into already bootstrapped AngularJS app) to variable in your app (main.js):
var app = angular.module('app',["ngRoute"]);
app.config(['$routeProvider', '$controllerProvider',
function($routeProvider, $controllerProvider) {
// remember mentioned function for later use
app.registerCtrl = $controllerProvider.register;
//your routes
$routeProvider.when('/', {templateUrl: 'partials/home.html'});
$routeProvider.when('/process1', {templateUrl: 'partials/process1.html'});
$routeProvider.otherwise({redirectTo: '/'});
}
]);
process1.html:
<script src="js/process1.js"></script>
<div ng-controller="P1Ctrl">
{{content}}
</div>
And now, in process1.js you use our registerCtrl:
app.registerCtrl('P1Ctrl', function($scope)
{
$scope.content = '...';
});
index.html probably remains the same. Check if your process1.js is being loaded (simply using console.log() right in the body of process1.js, not in P1Ctrl controller). If it isn't, include jQuery before Angular:
<script src="lib/jquery/jquery.js"></script>
<script src="lib/angular/angular.js"></script>
IMPORTANT: This method doesn't work with angular 1.2.0-rc.2 and 1.2.0-rc.3, because this little trick with jQuery doesn't work.
For more complex (and prettier) solution, with .js files as dependencies in route definitions, check that article: http://ify.io/lazy-loading-in-angularjs/ - it also works with rc.2 and rc.3. Here is plunk implementing described method: http://plnkr.co/edit/ukWikO5TVDtQ1l9WlrGD

Categories