I am trying to view my app after running Grunt Build. I use grunt serve:dist to see all production ready build but in the browser I get an infinite loop saying:
WARNING: Tried to load angular more than once.
I have read this occurs because the TemplateURL: may be wrong after concatenation. As in this post:
Tried to Load Angular More Than Once
But how do I fix this? Here is my app.js
/* global libjsapp:true */
'use strict';
var libjsapp = angular.module('libjsApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute'
]);
libjsapp.config(['$routeProvider', function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/posts.html',
controller: 'PostsCtrl'
})
.otherwise({
redirectTo: '/'
});
}]);
In my case this was due to the following html code:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Testapp</title>
</head>
<body ng-app="testApp">
<main ui-view>
<script src="bower_components/jquery/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<script src="scripts/main.js"></script>
</body>
</html>
As you can see, the <main> is not closed. This led to my variant of 'WARNING: Tried to load angular more than once.' issue.
This problem also is caused by using the current page as the templateUrl. This is especially problematic as it results in an infinite loop referencing itself over and over.
If you are getting an infinite loop that crashes your page, it's probably this. If you are getting CORS errors, it's probably due to including a script tag from another domain in your template.
$routeProvider.when('/', {
templateUrl: 'an/absolute/url/to/the/current/page.html'
});
I had this problem because my templateUrl path was wrong due to my index.html being in a different root structure. Try testing the URL path just using template instead of templateUrl.
Place an image in your views folder, and try this.
$routeProvider.when('/', {
template: 'Test Template <img src="views/pic.jpg"/>',
controller: 'PostsCtrl'
});
$routeProvider.otherwise({ redirectTo: '/' });
You should see "Test Template" and the image show up on your index page. If the image doesn't show up, your path is wrong.
I came across the same issue. But in my case, with webpack build two different Angular versions got packaged (Angular 1.5.5 and Angular 1.5.0).
Yeah I sorted it out by moving the post.html into partials and changing the templateUrl to partials/posts.html. I think this might be due to the Yo scaffold I used which was angular fullstack, because it work fine of the see project. Thanks anyway
The problem is in fact related to angular library being loaded too many times.
My reply can sound too obvious, but the code itself is fine and there's not much information on what the problem can be. If you can post your folder tree, maybe it can be useful.
In the meantime, please ensure these two things are ok before investigating further:
views/posts.html does not include a script tag with the call to angular.js library.
views/posts.html file is available in that position (maybe use a complete URI).
I confirm all above (usually routing errors or some error on resources paths or ng-app error).
I would like to add only a point to help to find the error (not in case of wrong ng-app).
If we suppose the server for angular is setted as follow:
/static/* for all static resources (js, css, png...)
/api/* rest api
/* all others call will be redirect to index.html
In this way all wrong path will return index.html instead of png, css, js and tpl files, even if is missing /static/ path or miss to return 404 for missing static resources.
in short: check the log on server witch paths are you calling opening the page, the error evidence could be found there.
You must change angular route '/'! It is a problem because '/' base url request. If you change '/' => '/home' or '/hede' angular will good work.
Sample:
Module.Js:
var application = angular.module('flow', ['ngRoute', 'ngResource']);
RouteConfig.Js:
angular.module('flow')
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/home', { templateUrl: '/home/index', controller: 'HomeController' })
.when('/error', { templateUrl: '/Error/Index', controller: 'ErrorController' })
.when('/login', { templateUrl: '/Account/Login', controller: 'AccountController' });
}]);
In my case, the cause of the warning was a redundant script inclusion of "angular-scenario.js" after "angular.js".
When I removed "angular-scenario.js" warning disappeared.
I recently got this error and the way I solved it was to go into the Web.config and change <compilation debug="false" targetFramework="4.5.2"/>
to <compilation debug="true" ... />
I hope this helps someone! Cheers!
Your solution might work locally for example if your running grunt serve, but when you run a grunt build your view might not be included in the dist directory. For example if you have a view and that view is in views>templates>modules anything more than two levels wont be added when you run grunt build by default. At least that was the case for me. Check if your html file is being included into the dist directory in views. If its not add your files manually to verify that it works, then update your grunt file acordingly.
In my case the problem was related to AngularJS Batarang Chrome Extension (version 0.7.1). Once I disabled the extension the error disappeared.
In my case, angular library and my angular module code is dynamically loaded inside another application which I dont have any control. And these are loaded on click of of a button. For the first time its working fine but when user clicks 2nd time the library and other files loads again and it gives me the warning.
WARNING: Tried to load angular more than once.
var isInitialized = element.injector();
if (!isInitialized) {
angular.bootstrap(angular.element(document.getElementById('#mainDiv')), ['defaultApp']);
}
This case is when the code takes to infinite loop somehow. Make sure you verify if there are any redirections in your code which are called multiple time.
In my case the template file (not string) was empty. when I filled the template file with simple html, the problem has been solved. Fill views/posts.html with some code.
We were accidentally trying to load a non-existent route in a ui-view. The route, however, did correspond to a valid URL that contained an Angular app. It instead loaded that Angular app into the ui-view, hence the multiple copies of Angular.
In my case app-view-segment="1" was missing and there was two references pointing to the same folder of angular in the index.cshtml file, in the #Scripts.Render lines.
Thanks for pointing to the angular routing.
Just to add one more possible scenario to this issue...
Behavior: everything works fine when loaded from the root URL, but you run into this issue whenever loading your page from any other route (or entering another route).
Likely reason: one of your nested components or pages is loading something from a relative path instead of an absolute path.
In my case it had to do with a referenced component loading its template with a relative path.
So, for example changing from this:
angular.
module('app').
component('profileSelect', {
// this line was the problem
templateUrl: 'static/angular/profiles/profile-select.html',
bindings: {}
});
to this:
angular.
module('app').
component('profileSelect', {
// making this an absolute path fixes it
templateUrl: '/static/angular/profiles/profile-select.html',
bindings: {}
});
Resolved it. Basically because you now have sub-paths those relative references no longer work, and angular decides to fail in this incredibly hard-to-decipher way.
Hopefully someone is helped by this answer. I just lost an hour+ of my life to it...
Last time this happened to me, it was a leading '/' in a route's templateUrl, which wasn't suppose to be there.
This time though, it was a bunch of views not getting rendered into the template cache after build because I've placed those views in a sub folder of a sub folder under the views folder. Gruntfile.js wasn't tuned to pick up 3rd level folders from '/views'.
To find out what was rendered in a yo-grunt build, you can look at .tmp/templateCache.js after the build finishes.
I do wish AngularJS LTS's team will find a way to better handle this kind of error, with some better clue as to where the problem is.
Hope this helps!
I ran into this issue and found that the problem occurred in my karma.conf.js file.
When specifying which file patterns to load into the browser, I used a wild card identifier to load AngularJS like so:
'path_to_angular/angular/*.js
If there's more than one file loading AngularJS within that directory, like angular.js and angular.min.js for example, then this error will be thrown.
To avoid this error, simply specify a single path with no wildcards.
'path_to_angular/angular/angular.js'
or
'path_to_angular/angular/angular.min.js'
should do the trick.
The issue/fix we had might be a little unique because we're using webpack + AngularJS.
We are using html-webpack-plugin. However, our index.html file also had
<script type="text/javascript" src="./bundle.js"></script>
The html-webpack-plugin automatically adds that line, so it was in our resultant HTML twice.
I ran into the same problem and that's why I'm landed here. However, none of the answers worked for me. It turns out that nothing is wrong in code, and the browser url is the culprit: it should be localhost:3000/#/, but somehow, I got something like localhost:3000/xxx/public/index.html/#/ in my browser. By the way, I'm using ui-router with node.js in WebStorm if it matters.
In my case it was an invalid resource link in index.html
<link rel="import" href="/somethingmissing.html">
Related
for a project, I am using Django on the back-end and AngularJs on the front end.
Basically, what I want is to run the Angular app only when the url starts with projectkeeper/.
In other words, lets say my website is example.com. I want the angular app to run for the URLs example.com/projectkeeper/dashboard/, example.com/projectkeeper/projects/ and so on, but not on example.com/about/.
Hope I have made myself clear. Anyway, in order to do this, I am doing the following with my code:
urls.py
urlpatterns = [
url(r'^projectkeeper/$', TemplateView.as_view(template_name='base.html')),
]
In the template base.html, I refer to my angular app obviously. For the angular routing, I have done the following:
myapp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/dashboard/', {
title: 'Dashboard',
controller : 'DashboardController',
templateUrl : 'static/app_partials/projectkeeper/dashboard.html'
})
.otherwise({ redirectTo : '/' });
}]);
So, ideally, what I thought was that going to example.com/projectkeeper/#/dashboard/ would run the DashboardController from my angular app. However, this is not the case, I only get an empty page which means the routing was incorrect.
Any solutions to this? As I said before, I want is to run the Angular app only when the url starts with projectkeeper/.
I think you're pretty close, there is few things to make this works(honestly, this is confusing to understand and I hope I didn't forget anything).
First, your URLs order is important, if you define something before the angular routes they will be rendered first, so use your django app's urls before the angular one.
Then, if you want to make angular know about the sub-path you need to define <base> tag in your header. In your case:
<base href="/projectkeeper/" />
(you can also define projectkeeperit in all of your where functions tho).
For the urls, I would change the regex to: r'^projectkeeper/.*'. Again, should be the last one in your urls list.
You will encounter other issues like the {{ }}, authentication issues, but those will stay for a different answer :)
Try out this ui router for angularJS
https://github.com/angular-ui/ui-router
It will be more helpful on nested views and problem like which you are facing currently.
I am trying to redirect to a template file after an Ajax call using:
window.location.href = "templates/somepage.html";
It goes to the page, however, on that page, the buttons won't load properly and the JavaScript won't get called when I click the buttons. I probably need some sort of callback because index.html needs to get called as well as templates/somepage.html.
NB: We are using the Ionic framework but I am not experienced with it, as I am a php developer. Also, I would prefer a non-jquery solution. Thanks.
The reason nothing works or displays correctly because the file you are redirecting to is missing all the core include (the CSS and JavaScript) files as can be seen below:
about.html
This is a base Ionic template file and as you can see it has no <script></script> or <link> tags.
<ion-view title="About" id="page9">
<ion-content overflow-scroll="true" padding="true" class="has-header">
</ion-content>
</ion-view>
Thus none of your CSS or JavaScript is working correctly.
Ionic is built on top of AngularJS so you can use the the state changer instead of directly accessing or redirecting to a template file as you are doing.
What you have to do is inject the $state in to your controller as can be seen in the example below:
routes.js
You should be already familiar with all of this, but you'll be referring to the state using myView.
[...].state('myView', {
url: '/my-url',
templateUrl: 'my/template/location.html',
controller: 'myViewCtrl'
});
controllers.js
In your controller, you'll inject the $state which will be used to change the view.
[...].controller('myCtrl', function ($state) {
/** This will be used to change to the route that we created above. **/
$state.go('myView');
});
I struggled with this too when I first started using Ionic and I stumbled across the solution and thought I'd help out.
Reading Material
Activating a State
$state.go() Reference
I have a homepage link that loads /register html page. But when I change css on the /register page and want to see it I have to go back to my localhost and then click the link again so the page loads again with new css. This is painfully time-consuming, is there a way to link /register with the page/route? Or at least remove /register from URL (so that localhost is only url for the whole app) so when the user refreshes the homepage welcomes him?
Homepage link:
REGISTER
View gets loaded like this
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when("/register", {
templateUrl: "/register",
controller: "registerController"
})
.otherwise("/");
$locationProvider.html5Mode(true);
}]);
This is an angular mechanic and is explained more in a recent question that I answered AngularJS + UI-Router - Manually Type URLs in HTML5 Mode without HashBang
Easy work around: use localhost/#/register instead to get to the page.
Since you are using
$location.html5mode(true);
This issue is directly related to how the files are being served to the browser. Your angular app itself only has one access point and that is your index.html page. When you type into your browser localhost/register, it is looking for the register directory, not the actual angular route. Since you've enabled html5 mode, it removed the hash bangs, which looks nice, but that requires additional configuration to be able to access the views individually without them.
Additional: If you want to remove the route URLs altogether, you will need to use stateProvider instead of routeProvider
Related article regarding stateProvider: Angular ui-router: Can you change state without changing URL?
Set in you html
<head>
<base href="/yor base url">
</head>
When my module does not load how can I load it correctly?
Suppose I have tens of controllers and I would like to separate each controller into its own file. For this example suppose I have one controller that lives in a file: controller.js
angular.module('pubmodule').controller( 'CreatePostController', ['$stateParams', '$scope','$http' ,function($stateParams, $scope, $http) {
}]);
and I have a module which loads from: base.js
angular.module( 'pubmodule', ['ngSanitize', 'ionic'] )
.run( function ( $rootScope, $state, $stateParams, PostTimelineService) {} );
I load each of these files from my html:
<script type="text/javascript" src="controller.js"></script>
<script type="text/javascript" src="base.js"></script>
When I load the files in the above order, I do not have access to pubmodule so I see:
Error: [ng:areq] Argument 'CreatePostController' is not a function, got undefined
I closely followed this question, but this question does not consider load order and that is the topic I am interested in. How can I separate my controllers into different files AND consider the order my module loads? Simply changing the order my html loads solves this error, but I am concerned that I do not have control over this when considering latency. The request for controller.js may come back first.
Latency doesn't matter in terms of load order. The browser will still load the files as they are declared in the html. So as long as your base.js file is referenced first you'll be ok. The browser will execute the code in order they appear. So if controller is declared after base but comes down first, then it won't be evaluated till base is done.
My sucpicion is the module.run() occuring after the controller.js in base.js.
On a side note if base.js is really the base it should be on the top of controller.js.
Nonetheless try adding your .run in the first js. But also make sure that all its dependencies are available prior to that...e.g. your PostTineLineService.
Checkout AngularJS documentation on the order of run with respect to its dependencies.
enter link description here
I am developing a single page application, with help of AngularJS and I'm new to it
I asked the same question before but haven't got any answer so I am rephrasing my question and ask it again
THE QUESTION:
What I need to do is to make my web app enabled to work offline for this purpose the html files which are rendered as view (for example home.html) should be included somehow in the index.html, So when clicking on the some links there should be no need to have access to a html file instead a part of the same page for example a dive will be rendered, what modifications should I make to project to get this done
at the moment I made different html files and use them as templates when rendering views,
the structure of app is like this :
- index.html
- pages
----- home.html
----- profile.html
here is the code for config the routes and controllers and views
var formApp = angular.module('formApp', ['ngRoute']);
formApp.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl : 'main',
controller : 'mainController'
})
.when('/profile', {
templateUrl : 'profile',
controller : 'profileController'
})
});
And and my main.html file for example is like this :
<div class="jumbotron text-center">
<h1>Main Page</h1>
<p>{{ message }}</p>
</div>
َand somewhere in the index.html I have
<div ng-view>
{{ message }}
</div>
The code works properly and everything is fine at the moment
To make your application work offline, you have to cache every file with the html5 cache manifest. Even the .html files, images, css, everything...
The native "old" caching won't work here, because it still requires to communicate with the server to have the "304 Not Modified" http code.
The manifest removes this step and doesn't even ask the server for the resources.
An example manifest:
CACHE MANIFEST
/angular.js
/index.html
/page/home.html
/page/profile.html
NETWORK:
*
How to include and use cache manifest check: http://www.w3schools.com/html/html5_app_cache.asp
For debugging:
Clearing a app cache under chrome enter url "chrome://appcache-internals/"
EDIT: Due to comment and off the topic
Instead of placing the html code in many own html files, you can include them in index.html like this:
<script type="text/ng-template" id="one.html">
<div>This is first template</div>
</script>
Then your templateURL is "one.html" without subpath.
Check docs: https://docs.angularjs.org/api/ng/directive/script
Hint:
You dont need to place any paths there. During rendering phase, angularjs will store every html file in the $templateCache under it's id placed in those script elements.
This might not be 100% applicable to you. Depending on the solution & or platform you're using... But I've got a prototype application that I'm working on currently, built in Angular and Node.
Although this was also my fist attempt at something like this... EG caching all the pages upfront. This seems to work quite well.
All my pages get converted to a cache friendly format during the build phase. But in my solution, they are still regular html pages.
home.tpl.html
<div class="well home-menu">
HOME
</div>
templates.js
angular.module('templates', ['home.tpl.html']);
angular.module("home.tpl.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("home.tpl.html",
"<div class=\"well home-menu\">\n" +
"HOME\n"+
"</div>");
}]);
controller
angular.module('myApp.home', ['templates'])
.config(function ($stateProvider) {
$stateProvider
.state('app.home', {
url: '/home',
templateUrl: 'home.tpl.html',
controller: 'HomeController'
});
})
.controller('HomeController', function ($scope) {
//do something
});
All this magic courtesy of html2js
grunt.loadNpmTasks('grunt-html2js');
...I do believe its possible to achieve this effect in various other ways that doesn't require grunt. For example manually creating the templates in the js file... but I wouldn't dream of recommending that route, as it could turn into a nightmare quickly