Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upservices / factories, what is going on? #14948
Comments
|
I am not sure what part of the docs doesn't add up (although admittedly the multitude of ways to create Angular services (hereafter "services") has been a common source of confusion). There are numerous resources on that subject, but in brief (quoting from the docs):
So, services are "things" that you can inject into other parts/components, such as directives, controllers, filters, other services etc. Angular's Inversion Of Control container is in charge of creating the service instances (one per injector), supplying the necessary "ingredients" (dependent values) as arguments and handing them to whoever requests them (through Dependency Injection). The "recipe" for how a service will de created is defined using one of the available methods: Basically,
That is exactly what it does. Using
For you usecase, you might want to just use the Regarding the following:
Note that But the main point is that whatever the factory function returns, is the "instance of the service" in the sense that it is the "concrete thing" that will be passed to anyone that requests it (through DI). And because services as (per injector) singletons, the exact same "thing" will be passed everytime. Afaict, everything works (and adds up) properly. BUT we always welcome suggestions (or better yet pull requests) with docs improvements, so by all means do come forward if you have ideas on how we can do a better job explaining these concepts. I am going to close this, since it is not actionable in its current form, but feel free continue the discussion below. |
|
@gkalpak I have long felt that the key point, of confusion around the |
|
Additionally, I have seen some highly skilled angular developers write code which reflects a misunderstanding of arbitrarity of this distinction. For example, I have seen this: (function () {
Function MyService ($http) {
this.$http = $http;
}
MyService.prototype.getById = function (id) {
return this.$http('/whatever?id=' + id);
};
angular.module('app', [])
.factory('MyService', ['$http', function($http) {
return new MyService($http);
}]);
}());Why didn't they write this? I believe it was because the documentation failed to adequitely explain the similarity and redundancy of the concepts. (function () {
Function MyService ($http) {
this.$http = $http;
}
MyService.prototype.getById = function (id) {
return this.$http('/whatever?id=' + id);
};
angular.module('app', [])
.service('MyService', ['$http', MyService]);
}()); |
|
Maybe they know the difference and they intentionally use it this way. Note that @johnpapa's styleguide suggests using
This is not 100% true, unless you use a constructor function as a factory, havig a return value (which is neither a good idea, nor necessary). Like I said, if you have an idea of how the docs could be improved, please submit a PR and we'll be more than happy to discuss |
|
the docs say that I am well aware of the ideologies behind factories and that they have some method that returns an instance of something depending on the parameters passed to them. working code(function () {
angular
.module("App")
.service("Form", FormService);
function FormService() {// SERVICE FUNCTION WRAPPER
function Form() {// REAL CONSTRUCTOR FUNCTION
this.roles = [];
this.name = "";
}
Form.prototype.addRole = addRole;
function addRole() {
this.roles.push("");
}
return Form;// RETURN REAL CONSTRUCTOR
}
})();In your factory example, you are returning a function which is indeed an instance of Function. But you are returning a new function just to push messages to the same message queue. Plus, the docs say that a factory returns an instance of a service, which isn't what was done in that example. A Function was returned. Why not just expose a single method to push onto a queue to begin with? |
|
The whole point of Again, for your usecase (where you don't need anything from DI), you could (and should) use (function () {
angular.
module('App').
value('Form', Form);
function Form() {
this.roles = [];
this.name = '';
}
Form.prototype.addRole = function addRole() {
this.roles.push('');
}
})(); |
|
Using |
This means that it should take the "thing" (whatever that is), that will be returned from the
In JavaScript there are no "services", so when we are talking about "services" in this context, we are referring to Angular services" (a.k.a. "substitutable objects that are wired together using dependency injection (DI)"). So, a constructor function (which is essentially just a function, which is essentially an Object) can be used as a service instance (i.e. as the "thing" that will be returned when someone requests for the service instance). I think much of the confusion comes from the fact that in JavaScript, functions are first class citizens and are objects themselves (everything is an object This is (more or less) how I like to think about it: // Assuming:
$provide.
service('FOO', FooService).
factory('BAR', barFactory).
value('BAZ', bazValue).
provider('QUX', quxProvider);...I imagine the following "dialogs" taking place inside the app: someone: Hey, $injector, I need my 'FOO'. sometwo: Hey, Mr. $injector, could I get some 'BAR' here? somethree: Yo, $injector dude, gimme some 'BAZ'? somefour: Could I get some somefive: So, $injector, my old friend, here's the thing: I need some 'FOO', some 'BAR', some 'BAZ' and some 'QUX'. (Yes, Angular components do speak to each other like this |
I am not sure if the angular team had mixed ideas about services and factories. But the code and ideas mentioned in the services section don't add up, not even on angular's site. If service registration takes a constructor function as the second argument, and its suppose to be invoked as a constructor would, with the
newkeyword, then why can't I treat it as a true constructor passing in parameters?Service
Controller
Factories
As for factories, your documentation states that, as well as other books, that factories should return service / class instances. However, this code contradicts. No instances were created and returned by the factory.