What is the difference of the below code
.factory('Service', ['$log', function($log) {}]);
.factory('Service', function($log) {});
both are working fine in my app.
The first one is considered safer when minified. I generally don't have a problem with the second version with my current minifier though.
Since Angular infers the controller's dependencies from the names of arguments to the controller's constructor function, if you were to minify the JavaScript code for PhoneListCtrl controller, all of its function arguments would be minified as well, and the dependency injector would not be able to identify services correctly.
The first factory with the added array, is used when the code is going to be minified to stop the code from breaking once it is minified. If you are not planning on minifying your code, either will work. If you are going to be minifying it, then go with the array syntax.
Related
I am starting to write a little library that uses angular. I want to write a directive that is not coupled to the first app that is initialized. I want to write a directive that somebody would add to their app and it would just work.
Instead of:
angular.module('realEstateApp', []);
angular.module('realEstateApp').directive(etc);
Just use:
angular.directive(etc)
If I can't do this, do you have some workaround to give me?
Angular directives need always to live within a module. What you have to do is define a module and then use it as a dependency in other modules. People will have to add Your module as a dependency to theyr module:
angular.module('myDirectiveModule', []);
angular.module('myDirectiveModule').directive(etc);
Then share your module, and people will have to do (after including your script):
angular.module('myModule', ["myDirectiveModule"]);
I injected the 2.1.1 version ngtagsinput like this into my controller:
app.controller('homeCtrl', ['$scope','$http','ngTagsInput', function($scope,$http){
}])
*NOTE: TESTED! add ngTagsInput into the function() will not make a difference...
I loaded the ngtagsinput lib after angularjs lib.
I wonder what else I could test to resolve the error of:
Error: [$injector:unpr] Unknown provider: ngTagsInputProvider <- ngTagsInput
http://errors.angularjs.org/1.2.9/$injector/unpr?p0=ngTagsInputProvider%20%3C-%20ngTagsInput
Don't get me wrong, I know basically this provider is not detected.
but my lib is found (did not report 404), I saw ngTagsInput used in its library....
So, its really bugging me the same solution no more works for this lib! What's special about this lib and why this error is there while I met all the standard to fix it?
It looks like you have tried to inject ngTagsInput into your controller, while you should be injecting it into your module as a dependency. For example:
angular.module('myApp', ['ngTagsInput'])
note module, not controller
You can see as per the creators example: https://github.com/mbenford/ngTagsInput#example
This happens because there are multiple types of injection used in angular. When you declare a module, you need to specify which other modules are available to use within your module.
See: https://docs.angularjs.org/guide/module
When you inject into say a controller, you are basically saying that you want to use a particular object inside it. That object must be a part of your module to be valid. For a third party library, this usually means adding it as a module dependency (as above), and then injecting any object that is part of that library into your controllers and services.
When I have an Angular directive that uses a controller I've been able to access the directive's scope in my tests by doing this:
element = angular.element('<my-directive></my-directive>');
element = $compile(element)($rootScope);
$rootScope.$digest();
scope = element.scope();
That enables me to set/get scope properties and directly call functions defined by the directive's controller.
However, as soon as I introduced jQuery to the project (required by another dependency I want to use) this stopped working. Specifically in the test element.scope() is returning undefined. Using dev tools I can see that this is not the case when the app is running for real – i.e. I can do $('.blah').scope() and get back a non-undefined value.
Anyone got an idea why this wouldn't work? I've added jQuery to my karma.conf.js (I'm using the Yeoman Angular generator) in the same order as it's included in the HTML file.
I found the problem. I'm running my tests in PhantomJS and was pulling in jQuery 2.0.3. Downgrading to jQuery 1.10.2 made everything work again. I'm kind of surprised that PhantomJS would have a compatibility issue but that seems to have been the problem.
I'm starting learning angularJS and find out yeoman is quite useful. But some how the controller/service/model generated by yeoman is not good for minifying later. Because due to what I see through the generated template (service in this case ) we have to inject the service implicitly.
But if we want to minify later, it's recommended to inject explicitly using $inject.
So my question is : Is it correct that what I understand ? If it's not then what is the correct way to inject with generated template from yeoman.
Otherwise, we shouldn't use generated template from yeoman at the moment if we want to do minify later, right ?
Thanks
so yeoman gives you something like this when generating a service
testApp.factory('Thing', function(dep1, dep2) {
return {/*...*/};
});
This is problematic when the code is minified, because the process of minification shortens function parameters, and angular uses them to infer which dependencies to inject.
To inject dependencies I recommend the inline annotation which looks like this
testApp.factory('Thing', ['dep1', 'dep2', function(dep1, dep2) {
return {/*...*/};
}]);
Notice the second argument is an array that lists the proper dependency names and that its final item is a function where such dependencies will be injected.
Edit: The Angular generators for Yeoman now support minification for both JavaScript and CoffeeScript code with the --minsafe flag as shown by #Ramiro
You can use the Yeoman Angular generators with the --minsafe, for example:
yo angular:controller user --minsafe
check other options here:
https://npmjs.org/package/generator-angular
Edit:
A follow up on this. It's now unnecessary to use the --minsafe flag, as yeoman comes with the ngmin app, which automatically converts all applicable code to be minifiable, and then minifies it :)
What exactly does the "inject" line do?:
function PhotoGalleryCtrl($route, $xhr) {
}
PhotoGalleryCtrl.$inject = ['$route', '$xhr'];
Are $route and $xhr predefined somewhere? Where to read about them?
Who said that the PhotoGalleryCtrl function has the .$inject method?
Both $route and $xhr are native AngularJS services, the latter has been replaced by $http in the most recent versions of AngularJS. They are part of the ng module.
You can read about them here
ng.$route
ng.$http
$inject tells angular to make available those services to the controller PhotoGalleryCtrl
Dependency injection and modules are core features of Angular. They both minimize global state and allow for better unit testing, you can read more about them here
Modules
Dependency Injection