Angular JS controller - angularjs

I am a little confused in the syntax for the controller in angular js:
Both the following controller work when I use {{ and }}.
Could someone tell me what is use of the parameters $scope and $filter before the function($scope..), the one in bold. Also when I remove one of these, I dont get the output.
'MyController1', ['$scope', '$filter',function($scope
app.controller('MyController1', ['$scope', '$filter',function($scope, $filter) {
$scope.an = $filter('uppercase') ("ankurbhatia");
}]);
Here I have removed the $scope and $filter before the function but it still works.
app.controller('DemoController',
function($scope, $filter) {
$scope.an= $filter('uppercase')('Ari');
});

It is usefull if you minify your JavaScript. If you state the "stringified" variable before, the minified JS will still find what the minifed variable should be.
Your JavaScript minifed will be
app.controller("MyController1",["$scope","$filter",function(r,a){r.an=a("uppercase")("ankurbhatia")}]);
If you dont specify the string before, it will look like this:
app.controller("MyController1",function(o,r){o.an=r("uppercase")("ankurbhatia")});
Se the section "A Note on Minification"
at https://docs.angularjs.org/tutorial/step_05

Related

Confusion between $scope's in controller and its function?

I'm new to UI. I do have confusion between $scope's in AngularJS. Please refer below snippet.
var mainApp = angular.module("mainApp", []);
mainApp.controller(['$scope', function($scope) {
$scope.name = "John";
}]);
So, what's the difference between $scope and function($scope)? Also how can we relate both? Is it required to have $scope parameter? Please explain me with an example. I really appreciate that.
Thanks,
John
1.When you apply Minification of Following Angular JS code:
var mainApp = angular.module("mainApp", []);
mainApp.controller(['$scope','$log', function($scope,$log) {
$scope.name = "John";
$log.log("John");
}]);
Minified Version :
var mainApp=angular.module("mainApp",
[]);mainApp.controller(["$scope","$log",function(n,o)
{n.name="John",o.log("John")}]);
2.When you apply Minification of Following Angular JS code:
var mainApp = angular.module("mainApp", []);
mainApp.controller(function($scope,$log) {
$scope.name = "John";
$log.log("John");
});
Minified Version :
var mainApp=angular.module("mainApp",[]);mainApp.controller(function(n,a)
{n.name="John",a.log("John")});
3.When you apply Minification of Following Angular JS code:
var mainApp = angular.module("mainApp", []);
mainApp.controller(function($log,$scope) {
$scope.name = "John";
$log.log("John");
});
Minified Version :
var mainApp=angular.module("mainApp",[]);mainApp.controller(function(n,a)
{n.name="John",a.log("John")});
You will Notice in Ex-2 and Ex-3 that you have interchanged the Dependency place of $scope and $log then also your minified version is the same ,this will give you dependency Injection error ,so we place a String value as String Value can't be minified as you can see in Ex-1.
It is not required to have $scope each time you define your controller but $scope provides important functionality like binding the HTML (view) and the JavaScript (controller). .
https://docs.angularjs.org/guide/scope
what's the difference between $scope and function($scope)?
When you do
mainApp
.controller(
['$scope', //line 1
function($scope) //line 2
{
}
]);
In line 1 it refers to $scope, which is an object that refers to the application model
In line 2 it is the variable (conveniently called $scope too) in which the (mentioned above) $scope object is injected. This variable can have any other name, $scope is used as a way to keep a suggestive reference through the whole code.
For instance, your example would work too if I change its name to myFunnyScope like this:
var mainApp = angular.module("mainApp", []);
mainApp.controller(['$scope', function(myFunnyScope) {
myFunnyScope.name = "John";
}]);
Also how can we relate both?
Taking as reference my previously posted snippet, you can tell the $scope object is being injected in the myFunnyScope variable, it means you use myFunnyScope as if it were $scope itself.
Is it required to have $scope parameter?
As long as you need to get access to all benefits provided by the mentioned $scope object, when you do minification it is required to inject the object ([$scope, ...) into the holder (function($scope) { ...) in order to not get the AngularJS application broken. Otherwise, no, you don't need to inject the object, but then you have to explicitly call it $scope in the function parameter so AngularJS knows it has to inject the $scope object inside it. This rule applies not only to $scope, but to all other AngularJS related services, factories, etc such as $timeout, $window$, $location, etc.
You might want to read about the AngularJS injection mechanism and consider using the controller as syntax for reasons explained here if you do not want to use $scope directly.

Inline Array Annotation - Why two $scopes are used for this code [duplicate]

This question already has answers here:
Why do angularjs controller declaration have this syntax structure?
(5 answers)
Closed 5 years ago.
I'm going through Angular JS Documentation. I'm not able to figure out one line that I mentioned in the below code. Can anyone explain ?
script.js:
angular.module('scopeExample', [])
.controller('MyController', ['$scope', function($scope) { // This line
$scope.username = 'World';
$scope.sayHello = function() {
$scope.greeting = 'Hello ' + $scope.username + '!';
};
}]);
index.html:
<div ng-controller="MyController">
Your name:
<input type="text" ng-model="username">
<button ng-click='sayHello()'>greet</button>
<hr>
{{greeting}}
</div>
I didn't understand this:
['$scope', function($scope) {}]
Here, why two $scopes are used.
Angular JS - Inline Array Annotation
Its used to avoid problems on minification.
After minification the code looks like:
['$scope', function(a) {}]
So Angular knows which dependencies to inject.
Otherwise it would look like
function(a){}
after minification and angular did not know which dependency is meant.
You will find more information in the AngularJS Docs (Dependency Injection)
https://docs.angularjs.org/guide/di
With the help of Michael, I found this on Angular JS Docs.
Inline Array Annotation
This is the preferred way to annotate application components. This is
how the examples in the documentation are written.
For example:
someModule.controller('MyController', ['$scope', 'greeter', function($scope, greeter) {
// ...
}]);
Here we pass an array whose elements consist of a list of strings (the
names of the dependencies) followed by the function itself.
When using this type of annotation, take care to keep the annotation
array in sync with the parameters in the function declaration.

Can't change 1 arg in controller in angularjs?

This is my angular code.
angular.module("app", []).controller("ctrl", function($scope){
$scope.name = "Name";
});
but, when I chaged the paramerter thats not working.
angular.module("app", []).controller("ctrl", function($para){
$para.name = "Name";
});
How to make it work and can't we use this in our other function?
Angular uses dependency injection based on the given parameter name. It doesn't know $para, so it won't get injected. You can however use the array notation where you explicitly say the name of the service to inject. The array notation is also necessary if you minimize your javascript code, so that angular still knows what to inject when your variables get renamed to a, b etc:
angular.module("app", []).controller("ctrl", ["$scope", function($para){
// $para is the $scope object
$para.name = "Name";
}]);
If your $para is a service, you have to register it so that angular knows what to inject:
angular.module("app", [])
.service("$para", function() {
//
})
.controller("ctrl", function($para){
$para.name = "Name";
});
The scope is the binding part between the HTML (view) and the JavaScript (controller). It is a special in angular.
Please read this https://www.w3schools.com/angular/angular_scopes.asp
'$scope' is a special service in AngularJS.
You can, however, create your own service '$para' and inject it if you want.
Check this.
Also, if you don't want to use '$scope', you can use the alternative 'controller as' syntax.
Read about it here.

I need a clarification about dependencies

What is the difference between:
myApp.controller('GreetingController', ['$scope', function($scope) {
$scope.greeting = 'Hola!';
}]);
And
myApp.controller('GreetingController', function($scope) {
$scope.greeting = 'Hola!';
});
Some of the examples add dependency for scope and some are not.
Thank you.
Both your samples have a scope dependency injected, the difference being the first one uses the array notation which allows you to create custom naming, won't break when minifying, etc... It's the recommended way. For example, this works fine:
myApp.controller('GreetingController', ['$scope', function(myScopeAlias) {
myScopeAlias.greeting = 'Hola!';
}]);
See it in action here:
angular.module('test', [])
.controller('GreetingController', ['$scope', function(myScopeAlias) {
myScopeAlias.greeting = 'Hola!';
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="GreetingController">{{greeting}}</div>
Dependency Annotation
Angular invokes certain functions (like service factories and controllers) via the injector. You need to annotate these functions so that the injector knows what services to inject into the function. There are three ways of annotating your code with service name information:
Using the inline array annotation (preferred)
Using the $inject property annotation
Implicitly from the function parameter names (has caveats)
Read more: https://docs.angularjs.org/guide/di#dependency-annotation
I just want to emphasis one point:
Always using the inline array annotation if you project need to do the Uglification(Most real project need a uglification).
Building minification-safe Angular.js applications

AngularJS 1.x custom filter can't be injected, unknown provider

I'm trying to create a custom filter, but when I try to inject it into my controller, I get an 'Unknown provider' error. I have checked and double checked all the references, but I can't see what's wrong.
I know that the file is referenced in my index.html correctly, it is loaded and can be found by the inspector. This is the code I have:
In my app.js:
angular.module('equiclass', ['equiclass.controllers',
'equiclass.services',
'ngRoute'])
.config(function ($routeProvider) {
$routeProvider
.when('/courses', {
templateUrl: 'views/courses.html',
controller: 'CourseCtrl'
// And some other stuff with routes
});
angular.module('equiclass.controllers', ['equiclass.services', 'equiclass.filters']);
angular.module('equiclass.services', []);
angular.module('equiclass.filters', []);
My filter:
angular.module('equiclass.filters')
.filter('testFilter', function() {
return function(input) {
return undefined;
};
});
And the controller:
angular.module('equiclass.controllers')
.controller('CourseCtrl', function ($scope, testFilter) {
});
Of course this is quite simplified, but it just doesn't work, and I can't see why. I have made several services and they all work and play along nicely.
If you want to use filter inside a controller you have to inject $filter attribute to your controller and can access it like
$filter('filtername');
You can use like
function myCtrl($scope, $filter)
{
$filter('filtername')(arg1,arg2);
}
You don't need to inject the filter itself.
This code...
angular.module('equiclass.controllers')
.controller('CourseCtrl', function ($scope, testFilter) {
});
Should be
angular.module('equiclass.controllers')
.controller('CourseCtrl', function ($scope) {
});
And inside CourseCtrl you should use your filter as you normally do.
Injecting the module 'equiclass.filters' into your module 'equiclass.controllers' is enough.
I had a similar issue and made a post about it on my blog.
--Edit
As n00dl3 mentions below the tricky part is how the auto-naming convention works in Angular. If you name your filter specialNumberFilter then when you inject it you need to refer to it as specialNumberFilterFilter. This allows you to use the filter as a function, which is what it is.
// In a controller
vm.data = specialNumberFilterFilter(vm.data, 'a');
But I believe you can also use the filter without injecting it into a controller if it is used in a string expression that is being evaluated by, say, a watch because this would be the same as the scenario when you are using it in a template.
// Inside a watch - no controller injection required
`$scope.$watch('vm.data | specialNumberFilter', function(new, old) { ... })`
According to Angular's documentation :
if you want to use your filter in a template
then you just need to inject it in your module and then use it like this {{ expression | filter }} or {{ expression | filter:argument1:argument2:... }} .
doc
if you want to use your filter in a controller, directive, and stuffs :
inject a dependency with the name <filterName>Filter, like this :
controller('MyController', ['filterFilter', function(filterFilter) {}]);
doc
so for this particular case :
angular.module('equiclass.controllers')
.controller('CourseCtrl', function ($scope, testFilterFilter) {
});
you didn't mention if it's in production or on a local server, but just in case you are minifying your files, try this:
angular.module('equiclass.controllers')
.controller('CourseCtrl', ['$scope', 'testFilter', function ($scope, testFilter) {
}]);

Resources