AngularJS infinite loop with ng-view - javascript

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!

Related

Angular: A controller with this name is not registered

I've been trying to figure this out for a few hours now, and I can't seem to find the problem. I've read some other questions with similar problems, but they don't have any solutions that have worked for me.
I am having trouble registering my controllers. I am not able to register controllers outside of the file in which I declare the app. Originally, I set up the 'MainController' in a separate file, which failed. I was getting an error saying that "The controller with the name 'MainController' is not registered". Once I put MainController in the same file as the app is declared, there were no problems. However, when I have a lot of code, I don't want all the controllers in the same file, as it will become too difficult to read. Here are examples of my code:
angular.module('myApp', ['ngRoute']);
angular.module('myApp')
.controller('MainController', MainController);
I am keeping other controllers in different files, and they are not registering. For example, in home.controller.js:
angular.module('myApp')
.controller('HomeController', HomeController);
function HomeController(HomeService) {
}
This controller will not register, and I don't know why. Each HTML partial in ng-view has its own controller, and the ng-view is within the MainController. Here is the app.config.js file:
angular.module('myApp')
.config(function($routeProvider, $locationProvider) {
$routeProvider.when('/home', {
templateUrl: 'views/home.html',
controller: 'HomeController as home'
}).when('/profile', {
templateUrl: 'views/profile.html',
controller: 'ProfileController as profile'
});
$locationProvider.html5Mode(true);
});
Here is index.html:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title>My App</title>
<script src="vendors/angular.min.js"></script>
<script src="vendors/angular-route.min.js"></script>
<script src="scripts/app.module.js"></script>
<script src="scripts/app.config.js"></script>
<scripts src="scripts/home.controller.js"></scripts>
<scripts src="scripts/profile.controller.js"></scripts>
<script src="scripts/main.service.js"></script>
<script src="scripts/home.service.js"></script>
<script src="scripts/profile.service.js"></script>
<base href="/" />
</head>
<body ng-controller="MainController as main">
<header>
<h1>My App</h1>
</header>
<!-- Content varies -->
<div class="container">
<ng-view></ng-view>
</div>
</body>
</html>
I have successfully built projects like this in the past without problem, but I can't find any issue compared to those projects. Any help is appreciated!
When I've had this issue in the past, it was related to script loading order, especially with using async script loading. You don't appear to be doing that.
To troubleshoot:
Fire a console log statement inside the controller's function body (console.log('registering controller x')). This statement will either not show up, or will show up after the error.
Angular used to (and I presume it still does) try to wait for app to load and all controllers to register to app before running the code. Either Angular isn't waiting on this controller, or this controller isn't running.
From there, you would verify that the reference to the file is correct (put a console.log at the top of the file), or determine how Angular decides when it believes all controllers are loaded and why it doesn't wait on your controller.
I haven't dealt with Angular since 1.2, because I think it's a pretty bad framework. But that was my experience then, and it seems like the same basic architecture for this. Back then it was relying on Document.ready. I really hope they don't do that anymore (that's where I ran into my async script loader problems).
Best of luck.

ngRoute return 404 Not Found error

I'm building a simple personal contacts management app using AngularJS. I put all my files inside htdocs/angular-contacts/ folder of my Mac machine.
index.html
<!DOCTYPE html>
<html ng-app='ContactsApp'>
<head>
<title>Contacts</title>
<base href='/'></base>
</head>
<body>
<h1>Contacts</h1>
<div ng-view=""></div>
<script src='/angular-contacts/jquery-2.1.3.min.js'></script>
<script src='/angular-contacts/angular.min.js'></script>
<script src='/angular-contacts/angular-route.min.js'></script>
<script src='/angular-contacts/angular-route.min.js.map'></script>
<script src='/angular-contacts/app.js'></script>
<script src='/angular-contacts/controller.js'></script>
</body>
</html>
app.js
angular.module('ContactsApp', ['ngRoute']);
.config(function($routeProvider,$locationProvider){
$routeProvider
.when('/contacts',{
controller: 'ListController',
templateUrl: 'list.html'
});
$locationProvider.html5Mode(true);
});
controller.js
angular.module('ContactsApp')
.controller('ListController',function($scope){
$scope.contacts = [];
})
list.html
<p>List views...</p>
Why I go to http://localhost:8888/angular-contacts/contacts, I got 404 Not Found error.
How to fix this problem? How to load that list.html?
Note:
I'm using MAMP (Apache).
AngularJS: v1.3.14
Angular Route: v1.3.14
That's because
$routeProvider
.when('/contacts',{
controller: 'ListController',
templateUrl: 'list.html'
});
expects the http://localhost:8888/contacts location, not the http://localhost:8000/angular-contacts/contats location.
You should add the prefix in your route declaration, or even better, conifgure the virtual host, so you'll be able to use a real domain, rather than the localhost's sub-catalogue.

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.

Why doesn't this angularjs application start?

I'm trying to build an angularjs application. Everything seems fine, there is no error, but it's not working. To remove other factors, I removed everything (requirejs etc.) and dumbed it down to a small html file.
Here is the js code in html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script>
angular.module('application', ['ngRoute']);
angular.module('application').config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {template: 'test content', controller: 'controller1'});
$routeProvider.otherwise({redirectTo: '/'});
}]);
angular.module('application').controller('controller1', ['$scope', function($scope) {
console.log('in controller1');
}]);
angular.bootstrap(document, ['application']);
</script>
</head>
<body>
</body>
</html>
Result I'm expecting to see is "test content" on page, and 'in controller1' in my console.
Can you tell me why it's not working?
Your are missing the ng-view directive that works together with the routes to display the template provided in the route config.
Working plunker
Code:
<body>
<div ng-view></div>
<script>
angular.module('app', [])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {template: '<p>test content</p>', controller: 'controller1'});
$routeProvider.otherwise({redirectTo: '/'});
}])
.controller('controller1', ['$scope', function($scope) {
console.log('in controller1');
}]);
angular.bootstrap(document, ['app']);
</script>
</body>
Angular JS bootstraps by using ng-app and ng-controller directive declared in html.
Refer this:
http://docs.deployd.com/docs/collections/examples/a-simple-todo-app-with-angular.md
Try adding adding this document ready test around you bootstrap call. It'll wait to call bootstrap until the document (DOM) is completely ready.
If you don't wrap bootstrap in the ready() call the browser may still be in the middle of constructing the DOM when angular builds it's view of the DOM. This can lead to angular being unaware of parts of your page, or worse (and this can be tough to debug).
angular.element(document).ready(function() {
angular.bootstrap(document, ['application']);
};
You can read more about that in this guide to angular initialization: http://docs-angularjs-org-dev.appspot.com/guide/bootstrap
Or you could use <html ng-app='application'> instead as others have mentioned if you want to go the more traditional route- but then you'd have to get rid of the angular.bootstrap call.

Angular routeProvider not loading next template

I am trying to have each item in a list have a button that uses $routeProvider to route to a template. However, I keep getting 404s when I hit the link (it goes to the right address, but no page loads). Any help on getting this code to work would be most appreciated:
angular.module('tipOutput', ['firebase', 'filters'])
.controller('Tips', ['$scope', 'angularFire',
function ($scope, angularFire) {
var ref = new Firebase('https://sitename.firebaseio.com/tips');
angularFire(ref, $scope, "tips");
}])
//routing to secondary pages
.config(['$routeProvider', function($routeProvider, $locationProvider) {
$routeProvider.
when('/tips/:tipId', {template: 'partials/tip-detail.html', controller: 'Tips'}).
otherwise({redirectTo: '/'});
}])
And, in case it helps, here's the code of my template:
<html ng-app="TipOutput">
<body>
<div ng-view></div>
<script type="text/javascript" src="http://static.firebase.com/v0/firebase.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular-resource.min.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/0.3.0/angularfire.min.js"></script>
<script type='text/javascript' src='https://cdn.firebase.com/v0/firebase-simple-login.js'></script>
<script src="js/app.js"></script>
</body>
</html>
Routes in a single page app are really virtual routes. How does the webserver software know what to do with that url? What are you doing to map this url to the html file that is serving your app? I suspect you might need to setup your httpd so that it understands what is going on.

Categories