What is $get in AngularJS? - angularjs

I haven't been able to find documentation in AngularJS docs on use-cases of $get. I'm trying to understand where and how to use it.
Below is an example from the AngularJS docs
function GoodProvider() {
this.$get = angular.noop;
}
Does this attach angular.noop to the GoodProvider function?

Yes, it attaches noop.
Look at the documentation on Providers, https://docs.angularjs.org/guide/providers
"The Provider recipe is syntactically defined as a custom type that implements a $get method. This method is a factory function just like the one we use in the Factory recipe. In fact, if you define a Factory recipe, an empty Provider type with the $get method set to your factory function is automatically created under the hood."

Related

Angularjs value service & factory service

In angular DOC
Register a value service with the $injector, such as a string, a number, an array, an object or a function. This is short for registering a service where its provider's $get property is a factory function that takes no arguments and returns the value service.
In the bold text, that says $get property is a factory function that takes no arguments, I know about the $get function in a angular providers which will be invoked using $injector.invoke() when an instance needs to be created and it is must have a $get function in a provider.
my question is about what is the underlying meaning of function that takes no arguments?
much appreciate if someone can describe the inner pieces of the angular values service & factory service with comparing both with the above doc quote. Thanks.
It means angular is creating a provider, like any other, that returns the value you're passing to it with module.value('name', value);. This type of provider is appropriate when there is no logic involved in building the value, and no dependency on some other service.
Comparison, yielding same result:
angular.module('myApp')
.value('baseUrl', 'http://localhost:8080/');
angular.module('myApp')
.factory('baseUrl', baseUrlFactory);
function baseUrlFactory(){
return 'http://localhost:8080/';
}

controllers are created using a factory function?

I am new to angularJS and going through angular docs.I came across this line controllers are created using a factory function
I tried to find what that means and found what is factory and service and providers but that does not fit here.
How controllers are created using a factory function?
Please explain what is the meaning of factory in this context.
The key quote you are missing from the previous section you are referring to is this:
"First, there is a new JavaScript file that contains a so-called "controller". More exactly, the file contains a constructor function that creates the actual controller instance. "
If this were an actual angular factory, it would make more sense. But, controllers are instances just like Angular factories, services, and providers.
A factory, is actually a Javascript design pattern, maybe reading here it will make more sense.
For the controller to work, the instance must exist for the two-way binding to be able to take place. So basically, an instance of the controller is created. The angular controller page explains it well with:
"When a Controller is attached to the DOM via the ng-controller directive, Angular will instantiate a new Controller object, using the specified Controller's constructor function. A new child scope will be available as an injectable parameter to the Controller's constructor function as $scope." Here's the link.
In the event of controllers though, you would most likely store items on the $scope and not 'this'. So they separate controllers from factories this way as they do not return an accessible instance of themselves and instead bind their properties to the view through $scope or 'this'.
TO BE CLEAR, I'm not saying that they are referring to Angular factories. I believe the reason for this phrasing is tied to the same wording for the service factory function:
"Application developers are free to define their own services by registering the service's name and service factory function, with an Angular module.
The service factory function generates the single object or function that represents the service to the rest of the application. The object or function returned by the service is injected into any component (controller, service, filter or directive) that specifies a dependency on the service."
They give this example:
var myModule = angular.module('myModule', []);
myModule.factory('serviceId', function() {
var shinyNewServiceInstance;
// factory function body that constructs shinyNewServiceInstance
return shinyNewServiceInstance;
});
So when you see them say created from a factory function, they are just saying using the following pattern:
.controller('PersonCtrl', [
'PersonFactory'
function(PersonFactory) {
this.name = 'Tom';
console.log(PersonFactory.name); //would print 'Tom'
}]);
.factory("PersonFactory", [
function () {
return {
name: 'Tom'
};
}]);
I hope that helps, or maybe someone could be more concise in my explanation and edit this description.
What this means is that you provide AngularJS with a function that it can execute as many times as it needs to produce instances of your controller. So to take the example from the page you linked to:
angular.module('invoice3', ['finance3'])
.controller('InvoiceController', ['currencyConverter', function(currencyConverter) {
this.qty = 1;
this.cost = 2;
this.inCurr = 'EUR';
this.currencies = currencyConverter.currencies;
this.total = function total(outCurr) {
return currencyConverter.convert(this.qty * this.cost, this.inCurr, outCurr);
};
this.pay = function pay() {
window.alert("Thanks!");
};
}]);
That function that starts on line 2 with function(currencyConverter) { is the factory function.
Whenever the page has a location that uses an InvoiceController, AngularJS will (essentially) do the following with that factory function, passing in any dependencies that it has:
var currencyConverter = ...; // obtain a currency converter from the factory
var theController = new thatFactoryFunction(currencyConverter);
and then it will use the value that is returned as your controller. It will do this separately for each InvoiceController indicagted the page, creating a separate instance for each one.
(I stress that the code above is purely an illustration of what AngularJS is doing and not an actual representation of the code that it uses.)
The creation of a controller instance is interesting. One would expect that it is created with new InvoiceController(...), and it's also suggested by the sentence More exactly, the file contains a constructor function that creates the actual controller instance, but that's not the case. Actually it's created like this:
instance = Object.create(controllerPrototype);
and later the constructor function is called as function:
return fn.apply(self, args); //self == instance
To be honest, we can only guess what the author meant by factory function. It could be the fact that controllers are not created by new. Maybe the the constructor function is therefore referred to as factory or it's the internal factory function. It could also just be bad wording or even a mistake.

Why functions are returned from angular services

While defining a angular services, one is expected to pass a Constructor function. This constructor function would be initialized using "new" keyword and the object returned by "new" is set to the service. so far so good.
However often I come across instances where programmers are creating services as below:
app.service('aObj', function AClass(){
return function(a,b){
alert(a + b);
};
});
This would be called as
aObj(1,2)
Although I undertsand that aObj will now end up being a function, I cannot understand why programmers initialize their services this way. Constructor functions usually would have a definition like:
app.service('aObj', function AClass(){
this.var1 = undefined;
this.calculate = function(b){
alert(this.var1 + b);
};
});
Then eventually one would call this as
aObj.var1 = 1;
aObj.calculate(2);
Can someone elaborate on the purpose of defining services using the former method ?
Plnkr: http://plnkr.co/edit/tpl:FrTqqTNoY8BEfHs9bB0f
This depends on what kind of API you want to expose from your service.
Return an object and call them as MyService.methodA() and MyService.methodB() if the service is a container for exposing several closely related methods. Angular's $location service is an example of this.
If the service exposes only a single public method, then it can be more convenient for users of the service to call it as MyService() rather than MyService.theOnlyMethod(). Angular's $compile service is an example of this.

Do Angular Directive Factory Functions Get Invoked as Constructors of Functions

In Angular, when registering a directive to a module, does the directive factory function get invoked using new or just with simple function call?
eg.
var MyDirective = function() {
return {
link: function() { ... }
};
}
module('myMod', []).directive('myDirective', MyDirective);
Does MyDirective get called internally as:
... = MyDirective();
or as
... = new MyDirective();
The Angular Guide on providers states:
Earlier we mentioned that we also have special purpose objects that
are (...) are Controller, Directive, Filter and Animation.
The instructions for the injector to create these special objects
(with the exception of the Controller objects) use the Factory recipe
behind the scenes.
This fact be clearly seen in compile.js source code. And because we know that factory recipe in Angular simply invokes the function (with its dependencies, via $injector.invoke(fn)) so the correct answer to your question is ... = MyDirective();
It is invoked using an $injector, i.e. $injector.invoke(MyDirective), so that dependencies can be resolved and injected. Internally, $injector.invoke call MyDirective(), without the new, and pass in the dependencies as arguments.

Which Angular provider for function syntax?

Let's say I have a provider named lookup. It's used like this:
.controller('lookupCtrl', ['lookup', function(lookup) {
this.values = lookup('monkey');
}]);
What is lookup? Is it a service()? Is it a factory()? A value()?
In this particular case it can be any of those.
lookup could be a value if you created a regular, plain-old JavaScript object and then used the Value provider, naming your object "lookup". Even though a value is typically a simple type, it could be an object, and this would work.
lookup could also be a factory if you used the factory provider, in which case, you specify a function which returns an object. The object you return is the exact same object that's injected in any routine like the above that requests 'lookup'
And finally, lookup can also be an angular service. If you did that, the service provider would specify a function that returns a "newable" object. So the thing you return will be a function which Angular will "new", and the result of that will be passed to anyone who requests a 'lookup' instance. Note that, even in this case, Angular instantiates your service one and only one time. The difference between factory and service is subtle. Think of a service returning a "class" that angular instantiates once and reuses that one instance. And a factory uses the object that you returned to angular.
The answer is "D: All of the above"
As a service:
.service('myService', function(){
return function(someParam){
console.log(someParam);
};
});
As a factory:
.factory('myFactory', function(){
return function(someParam){
console.log(someParam);
};
});
As a value:
.value('myValue', function(){
console.log(arguments);
});
Here is a Plunkr... look at the console output.

Resources