What is the difference in minifying these two pieces of code? - angularjs

i have the following non minfied and minified version code for controller:
non-minified version code :
phonecatApp.controller('PhoneListCtrl', function PhoneListCtrl($scope, $http) {
//code for controller
});
minified version code :
phonecatApp.controller('PhoneListCtrl', ['$scope', '$http',function PhoneListCtrl($scope, $http) {
//code for controller
}]);
i don't know why minified version code is preffered ? what is the difference between minified and non-minified version code ?

Minification renames variables (among other things). Your first sample will no longer work when minified, as angular won't know what to inject when $scope and $http are renamed. Your second example, using the array syntax, tells angular what to inject regardless of the variable names.
(There are syntax errors in both of your examples: PhoneListCtrl($scope, $http) should be function PhoneListCtrl($scope, $http).)
Note: when using named functions as you are, there's another option for minification-safe angular code:
phonecatApp.controller('PhoneListCtrl', PhoneListCtrl);
PhoneListCtrl.$inject = ['$scope', '$http'];
function PhoneListCtrl($scope, $http) {
//code for controller
}
Finally, if you really prefer your first example, you can use ng-annotate to pre-process your angular code and make it minification-safe.

Related

How to define an angular-meteor controller?

In this tutorial, the controller is:
angular.module('socially').controller('PartiesListCtrl', function ($scope, $meteor) {
$scope.parties = $meteor.collection(Parties);
});
In another tutorial, the controller is:
angular.module('simple-todos').controller('TodosListCtrl', ['$scope', '$meteor',
function ($scope, $meteor) {
$scope.tasks = $meteor.collection(Tasks);
}]);
Are the above identical?
It are two different notations. Both will work.
The second example uses "annotation" and is used when you are going to compress/uglify the code. Compressing your code will replace your service names and would break your code. Since the strings will not be replaced by the urligfier, Angular can use this to figure out what dependancies to inject.
Check out the Dependency Annotation part on this link:
https://docs.angularjs.org/guide/di
If you use a taskmanager to minify your code, there are ways to have this done for you. An example can be found here: https://github.com/mzgol/grunt-ng-annotate

Different syntax in Angular for controller, services and others

What is the difference between
app.controller("MyCtrl", function($scope, $http){
//...
});
and
app.controller("MyCtrl", ["$scope", "$http", function($scope, $http){
//...
}]);
Even though both gives the same result and no error. In fact the first one makes code clean and less to write. Also it is same in services, directive. Can someone give me a small brief about it.
No functional difference. Using .controller('ctrl',['$scope', function($scope){...} is to allow a minified version to be read correctly.
A Note on Minification - AngularJS
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 MyCtrl controller, all of its function arguments would be minified as well, and the dependency injector would not be able to identify services correctly.
We can overcome this problem by annotating the function with the names of the dependencies, provided as strings, which will not get minified. There are two ways to provide these injection annotations:
Create a $inject property on the controller function which holds an array of strings. Each string in the array is the name of the service to inject for the corresponding parameter:
function MyCtrl($scope, $http) {...}
MyCtrl.$inject = ['$scope', '$http'];
app.controller('MyCtrl', MyCtrl);
Use an inline annotation where, instead of just providing the function, you provide an array. This array contains a list of the service names, followed by the function itself:
function MyCtrl($scope, $http) {...}
app.controller('MyCtrl', ['$scope', '$http', MyCtrl]);
Both of these methods work with any function that can be injected by Angular, so it's up to your project's style guide to decide which one you use.
When using the second method, it is common to provide the constructor function inline as an anonymous function when registering the controller:
app.controller('MyCtrl', ['$scope', '$http', function($scope, $http) {...}]);
Adding to wzVang's answer. You can follow your first syntax. i.e
.controller('ctrl', function($scope){
});
without any problem. It is readable. But you should minify your code in production. Then you can use ngAnnotate.

Angularjs $scope in controller

Just to mention that, I am a very much newbie in Angularjs.
While writing a controller I see I can use
controller('MyController', ['$scope', function($scope) {}])
or
controller('MyController', function($scope) {})
What is the difference between the both ?
Both are same.
When the javascript code is minified, all local variables in the function are changed to smaller variables to reduce size. for example.
function (largevariablename){
largevariablename = 123;
}
will be converted to
function (a){
a= 123;
}
But in case of angular if $scope is minified to s. Then the dependency injection fails searching for s. So angular injector will inject the the string value it finds in the array and inject it instead of the local varaiable in you define it in below way
controller('MyController', ['$scope', function($scope) {}])
So incase if your code in not going to be minified you can use the simple version
controller('MyController', function($scope) {})
This is mainly used for minification. When you minify the js
controller('MyController', function($scope) {})
will be converted to
controller('MyController', function(a) {})
and it will give the error for a is undefined. When you provide the dependency as
controller('MyController', ['$scope', function($scope) {}])
it will map a to $scope and it will work fine.
In fact, you should not use callbacks(Anonymous Functions) directly to define controllers.
You should use separate functions and $inject module to manually identify your dependencies.
controller('MyController', MyController);
MyController.$inject = ['$scope'];
function MyController($scope){
};
Why use named functions ?
This produces more readable code, is much easier to debug, and reduces
the amount of nested callback code.
Why use $inject ?
This technique mirrors the technique used by ng-annotate, which I
recommend for automating the creation of minification safe
dependencies. If ng-annotate detects injection has already been made,
it will not duplicate it.
Also, this safeguards your dependencies from being vulnerable to
minification issues when parameters may be mangled.
This is extracted from well-know John Papa Angularjs Style Guide

Difference between controller definitions in AngularJS [duplicate]

This question already has answers here:
Why do angularjs controller declaration have this syntax structure?
(5 answers)
Closed 5 years ago.
When I run the code, Option A is failed but not sure what the reason is.
angular.module('app').controller('controllerA', function($scope, $http) {
// code
}
angular.module('app').controller('controllerB', ['$scope', '$http', function($scope, $http) {
// code
}]);
I tried to test it on Angular 1.x JSFiddle, but both of them work well.
Help me!
This makes much difference in the minification process. if you are using angular.min.js library then in the production, option A fails. in JSFiddle u might use angular.js lib. That's why both scenarios work.
Check this for more information about minification
Both will work, but you should follow the second example, which uses the Array syntax so you can minify your code without worrying about the minifier renaming function parameters
try below example
var myApp = angular.module("app", []);
myApp.controller("controllerA", function ($scope) {
});
myApp.controller("controllerB", function ($scope) {
});

minifying angular

I have this interest in automate/simplify angular project with a compiler tool, which might work on everything else, but angular inject and namespacing is awkward enough to escape compiler knowledge. What is the best/professional method for doing this?
thanks, just one last thing,
app.controller('ctrl',['$rootScope',function($rootScope){
...
}]);
works when minified, but how do I minify
app.config(['$routeProvider', function($routeProvider){
}]);
and does it work when I minify successive actions?
app.controller(...).directive(...).run(...)
In Angular, you need to annotate functions for the injector to know which dependencies you want to inject in your function. There are basically three ways to inject dependencies in your function which are being described on official angular website. The three ways are:
1.Use the inline array annotation
yourModule.controller('yourController', ['$scope', function($scope) {}]);
2.Use the $inject property annotation
var yourController = function($scope) {};
yourController.$inject = ['$scope'];
yourModule.controller('yourController', yourController);
3.Implictly from the function parameter names
yourModule.controller('yourController', function($scope) {});
Now when you minify your project, your dependencies names will get renamed.
In first case your code will be like
yourModule.controller('yourController', ['$scope', function(e) {}]);
In third case your code will be like
yourModule.controller('yourController', function(e) {});
It will break your app because angular has no way to recognize your dependency name. So it is advised never to use implicit dependency injection in your project. From the above two inline array annotation is the most popular way amongst programmers.
I would recommend using https://github.com/olov/ng-annotate. It will allow you to write your code like follows.
angular.module("MyMod").controller("MyCtrl", function($scope, $timeout) {
});
and then ngAnnotate turns it into the following which is safe for minification.
angular.module("MyMod").controller("MyCtrl", ["$scope", "$timeout", function($scope, $timeout) {
}]);
The minifyer leaves strings untouched, that's why we use the array notation.
Chaining methods wont change the way the minifyer keeps strings intact.
var app=module(myapp);
app.config(['$routeProvider', function($routeProvider){
$routeProvider.dosomestuffs()
}]);
will be minified in something like
var a=module(myapp);
a.config(['$routeProvider', function(b){
b.dosomestuffs()
}]);
but angular will still find its way around thanks to the '$routeProvider' string.
If you always use annotations there should not be problems minifying angular scripts.
app.controller(['$scope', function(mrScope) {
mrScope.yourProperty = 'it does not matter the dependency variable names if you use annotations';
}]);
As long as you use the array notation for the dependencies you are injecting, no minification trouble is expected. The minification tool you are using should handle any of your examples without trouble (on my project we're using uglify to accomplish that).
In fact, for oddly named injections (named with dots and chars that result in invalid function names like ABC.CDE), the array notation is the best way to inject them.
I had the same problem when minifying, and like you, it only failed for the $routeProvider config elements.. The answer for me was to use the $inject method like Himanshu says for my configs, even though the syntax you show for your first example works for my controllers. So I'll post my .config() code here since I don't see it specifically listed in the answers above:
var app = angular.module('myApp');
var RouteProviderConfig = function ($routeProvider) {
$routeProvider
.when(...)
.otherwise(...);
};
RouteProviderConfig.$inject = ['$routeProvider'];
app.config(RouteProviderConfig);
This fixed my error for configs, but my controllers work the way your first example is written:
app.controller('ctrl',['$rootScope',function($rootScope){
...
}]);
The Angular Documentation seems to suggest that both ways should work, so I think it's possible there is a bug with configs, or $routeProvider, or something else entirely...

Resources