I'm attempting to make some small tweaks to my config to hopefully improve performance slightly. I read through the Angular docs here and they mention disabling comment and CSS class directives. I tried to do so with the below code in my config, but I keep getting TypeError: $compileProvider.commentDirectivesEnabled is not a function or TypeError: $compileProvider.cssClassDirectivesEnabled is not a function errors.
Note: I'm running Angular 1.4.9
'use strict';
angular.module('app')
.config(compilationConfig)
;
compilationConfig.$inject = ['$compileProvider'];
function compilationConfig($compileProvider) {
$compileProvider.debugInfoEnabled(false);
$compileProvider.commentDirectivesEnabled(false);
$compileProvider.cssClassDirectivesEnabled(false);
}
Solved this myself. This functionality was introduced in 1.6.0 so you need to upgrade to take advantage of these methods.
Related
Suppose that I have an SPA written via AngularJS 1.x.
It has a single app module defined like this:
var app = angular.module('app', ['ngAlertify', 'ngRoute', 'ui.bootstrap'])
I also have several controllers which are defined in separate *Ctrl.js-files. What is the appropriate way to define them?
I see two options here. The first one is
app.controller('LoginCtrl', function($scope) { /* ... */ });
and the second one is
angular.module('app').controller('LoginCtrl', function($scope) { /* ... */ });
Which one is better and most common-used practice? Is there any downsides of using either of them?
If I understand your question correctly then you wan to know different between
app.controller('LoginCtrl', function($scope) { /* ... */ });
vs
angular.module('app').controller('LoginCtrl', function($scope) { /* ... */ });
In above two in first method app is a global object which you declared somewhere i.e. in app.js like
var app = angular.module('app',[]);
In this case app is a global variable which will be accessible throughout your entire application. which I believe is not a good thing to use global variable
in our application.
In second method we are using global angular object to create a controller so that in this we will not be using global variable. In this case app.js will look like
(function(){
'use strict';
var app = angular.module('app', []);
....
....
....
....
})
In this case app variable will not be available anywhere apart from this file.
So I belive second method is better than first one.
My personal preference is to use app.controller('LoginCtrl', function($scope) { /* ... */ }); as this makes it easier to reuse the controller in another project with little to no changes, without those annoying module not found errors because you forgot to rename the module when reusing the file
I think that depends a bit on the personal style of writing. One thing is that while working with AngularJS 1.x.x you can have different styles of writing code, method stacking etc.
Personally, I prefer app.controller('LoginCtrl', function($scope) { /* ... */ }); mainly because you can easily preview your controller and distinguish it from thge module. Another bonus I see of having a clearly defined separate module is that you can easily check what includes you have ('ngAlertify', 'ngRoute', 'ui.bootstrap').
Most commonly used as far I have seen, even here on SO, is the method that I previously mentioned. Yet again this is something that is more reflective of personal style rather than strong pre-requirements of writing code. I hope that helps to some extend.
None of the above. The purpose of modules is to keep the application modular and not pollute global scope.
You can have var app = ... but this should be done inside IIFE once per file.
Another issue with modules is the precedence. If the application uses angular.module('app') module getter, the files should be loaded in specific order, in order for the module to be defined when it is retrieved in other files. This creates problems if they aren't, for example when they are concatenated in alphabetic order.
The solution is to use one module per file. This makes the application truly modular, independent of file loading order, also benefits testability. See also this answer for how this pattern supposed to work.
You can use module setter and getter methods for implementation of controllers in different file.
Suppose myApp.module.js
angular.module('myApp', []); //Setter method, registring module
In myApp.homeCtrl.js
var myApp = angular.module('myApp'); // getter method, getting the module already registered.
myApp.controller('homeCtrl', [function()]{ })
For more info check this https://toddmotto.com/angular-modules-setters-getters/
The second approach your are taking about is better because it uses the already created module and doesn't create the new module but with the first approach you are using global variable that is not recommended
I've got a bunch of working unit tests for various Angular (1.4.7) directives, and I'm using Karma, Jasmine and Sinon for testing.
I'm trying to add a unit test for a new directive, which is the only directive I currently have that uses $window but I'm seeing a cryptic error in the console output:
TypeError: 'undefined' is not an object (evaluating 'this.proxy.toString')
This error is coming from sinon.js at line 2372.
I'm doing all the 'normal' things in a directive unit test such as creating a fake element that has the directive as an attribute:
testElement = document.createElement('div');
testElement.setAttribute('data-my-directive');
document.body.appendChild(testElement);
And compiling the directive:
$compile(testElement)($scope);
I'm using $provide to try mock the $window object:
module('app', function ($provide) {
$provide.value('$window', { id: 'test' });
});
But as soon as I try to use $window in the file being tested, the error shown above is thrown.
As I say, I have a bunch of other unit tests for other directives, services and controllers working as expected, so everything appears to be setup correctly. It's just this particular test.
Any ideas?
I am not sure if this is the same bug, but just a couple of days ago a fix to similar issue was got solved on sinon github:
https://github.com/sinonjs/sinon/pull/833
Fix contains lines:
var callStr = this.proxy ? this.proxy.toString() + "(" : "";
where the null check is one thing and several other lines.
This fix is at file lib/sinon/call.js in commit 7a18eb5.
I am not sure if this is same, because file is different and so is line, too. Still, this was so interesting that I would try latest sinon version and see if this gets fixed. It may be though, that similar error is in several parts of sinon, if the coder is for example same in both files.
I'm using Meteor, Angular and Ionic. I'm having a hard time changing from state A to state B as I keep getting the error 'only one instance of babel/polyfill is allowed'. I tried cleaning up the following code as much as possible. Note that I can change to other states successfully.
Here's my routes.js file:
.state('create-group', {
url:'/create-group:/:buddyId',
templateUrl: 'client/templates/create-group.ng.html',
controller: 'createGroupCtrl'
})
Here's my State A template:
<ion-item ng-repeat="buddy in buddies" ng-click="createGroup({{buddy}})">
</ion-item>
Here's my State A controller:
angular
.module('app')
.controller('whosDownCtrl', whosDownCtrl);
function whosDownCtrl ($scope, $state, $ionicScrollDelegate, $timeout, $meteor) {
$scope.createGroup = createGroup;
function createGroup(buddy) {
$state.go('create-group', { buddyId: buddy._id});
}
};
Here's my State B controller:
angular
.module('app')
.controller('createGroupCtrl', createGroupCtrl);
function createGroupCtrl ($scope, $stateParams) {
var clickedUser = $stateParams.buddyId;
}
Can anyone see what i'm doing wrong?
Did you manually add a babel/ecmascript package to meteor?
Check your .meteor/packages file and your .meteor/versions file because that error means there are multiple conflicting versions of babel added to your project.
And since all babel related meteor packages are independent wrappers, it is very likely to get such conflict.
Remove the "excess" babel packages and you'll be good to go.
I know this is very old question but I landed here while analysing my issue. Posting here my learning as it may help others.
I was also getting the same error in my project. It was happening because there were issues with correct template and controller resolution.
Here is a related github issue that helped in clarifying: https://github.com/Urigo/angular-meteor/issues/870
Use hardcoded template instead of templateUrl to analyse the issue properly.
I am trying to build an angular app "the right way" using various style guides as my inspiration. John Papa's being the most notable. Most say I should wrap angular components in Immediately Invoked Function Expressions (IIFE) and separate them into different files. This works on everything except directives.
Am I doing something wrong or if I should not use IIFEs for directives or use them in a different way?
Here is my jfiddle of it not working:
http://jsfiddle.net/HB7LU/14140/
Here is my jfiddle with it working without IIFEs:
http://jsfiddle.net/8kfpf9aq/
The only difference is wrapping in:
(function() {
'use strict';
//code
});
I have tried it and it works similarly in several version of angular 1, 1.3, 1.4.
I think your problem might be that you're not invoking the IIFE. It should look like this
(function() {
'use strict';
//code
})();
or this
(function() {
'use strict';
//code
}).call(this);
I am having a problem with Angular JS receiving an error : Uncaught Error: [$injector:modulerr].
My JS-file looks
angular.module('MyApp', ['ngRoute']);
angular.module('MyApp',['ngResource']);
function TwitterCtrl($scope,$resource){
}
I also included angular-route-js
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular-route.min.js">
Angular documentation says the problem is http://docs.angularjs.org/api/ngRoute
In development environments I recommend you to use not minified distributives. And all errors become more informative! Instead of angular.min.js, use angular.js.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.js">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular-route.js">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular-resource.js">
Try adding this:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular-resource.min.js"></script>
Try adding:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular-resource.min.js">
and:
angular.module('MyApp', ['ngRoute','ngResource']);
function TwitterCtrl($scope,$resource){
}
You should call angular.module only once with all dependencies because with your current code, you're creating a new MyApp module overwriting the previous one.
From angular documentation:
Beware that using angular.module('myModule', []) will create the
module myModule and overwrite any existing module named myModule. Use
angular.module('myModule') to retrieve an existing module.
Make sure you're function is wrapped in a closure, complete with the extra () at the end:
(function(){
var app = angular.module('myApp', []);
})();
I previously had the same issue, but I realized that I didn't include the "app.js" (the main application) inside my main page (index.html).
So even when you include all the dependencies required by AngularJS, you might end up with that error in the console. So always make sure to include the necessary files inside your main page and you shouldn't have that issue.
Hope this helps.
The problem was caused by missing inclusion of ngRoute module. Since version 1.1.6 it's a separate part:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular-route.min.js"></script>
var app = angular.module('myapp', ['ngRoute']);
This is getting reference from: AngularJS 1.2 $injector:modulerr David answer
I had the same problem. You should type your Angular js code outside of any function like this:
$( document ).ready(function() {});
I got this error because I had a dependency on another module that was not loaded.
angular.module("app", ["kendo.directives"]).controller("MyCtrl", function(){}...
so even though I had all the Angular modules, I didn't have the kendo one.
ok if you are getting a Uncaught Error: [$injector:modulerr] and the angular module is in the error that is telling you, you have an duplicate ng-app module.
Make sure that the variable that holds your angular.module is structured correctly.
This will fail with "Uncaught Error: [$injector:modulerr]":
var angApp = angular.module("angApp");
This works:
var angApp = angular.module("angApp", []);
It's a sneaky one since the error message doesn't point to one thing in particular (Thus the wide variety of answers). Additionally, most js linters won't catch the particulars. Keep at it!
I had exactly the same problem and what resolved it was to remove the closure:
$(function(){
var app = angular.module("myApp", []);
app.controller('myController', function(){
...
});
});
becomes:
var app = angular.module("myApp", []);
app.controller('myController', function(){
...
});
The error means that the dependency injector was unable to locate the dependency 'ngResource'. The script tag in the accepted answer provides this dependency.
You will also get the same error if you add any custom modules in the dependencies but did not add the script tag for including the '.js' file containing the dependency.
Just throwing this in in case it helps, I had this issue and the reason for me was because when I bundled my Angular stuff I referenced the main app file as "AngularWebApp" instead of "AngularWebApp.js", hope this helps.
I had also same issue, I have just removed following line of code from BundleConfig.cs file and my code is working fine.
BundleTable.EnableOptimizations = true;
Do not load the javascript inside the cdn link script tag.Use a separate script tag for loading the AngularJs scripts.
I had the same issue but I created a separate <script>
Then the error gone.