confused about service vs factory

759 views
Skip to first unread message

John Huntjens

unread,
Dec 7, 2012, 6:30:10 AM12/7/12
to ang...@googlegroups.com
As I understand it, when inside a factory I return a object that gets injected into a controller. When inside a service I am dealing with the object using this and not returning anything. 

I was under the assumption that a service was always a singleton, and that a new factory object gets injected in every controller. However as it turns out, a factory object is a singleton too?

Example code to demonstrate:

var factories = angular.module('app.factories', []);
var app = angular.module('app',  ['ngResource', 'app.factories']);

factories.factory('User', function () {
  return {
    first: 'John',
    last: 'Doe'
  };
});

app.controller('ACtrl', function($scope, User) {
  $scope.user = User;
});

app.controller('BCtrl', function($scope, User) {
  $scope.user = User;
});

When changing user.first in ACtrl it turns out that user.first in BCtrl is also changed, e.g. User is a singleton?

Peter Bacon Darwin

unread,
Dec 7, 2012, 6:56:57 AM12/7/12
to ang...@googlegroups.com
The difference is:

- factory('someService', someFactoryFn) : Angular will just calls someFactoryFn, once, the first time it needs someService.
- service('someService', SomeConstructorFn) : Angular will do new SomeConstructorFn, once, the first time it needs someService.

Pete



--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en-US.
 
 

Daniel Szak Ferenc

unread,
Dec 7, 2012, 7:01:07 AM12/7/12
to ang...@googlegroups.com
Hi John,

first of all, if You haven't already, make sure to watch this video about $provide methods (the second speaker, Wes Alvaro wraps up -almost- everything You need to know about the topic) and the slides of Wes.

My understanding is, that although You use the modules factory method - You are creating a service with it... factories -as Wes defines them- are "providers with only a $get method". In Your example You return an object instead of a function.

Hope the presentation of Wes will give You as much insight as it did for me, hooray for AngularJs meetups!
The angular_team.do("ROCK!");

Happy coding.

ps:
ok, the extracted essence (summary for executives) are these plunkers on service and factory - both found in the slides and video.

John Huntjens

unread,
Dec 7, 2012, 7:21:24 AM12/7/12
to ang...@googlegroups.com
Thanks Peter and Daniel

@Daniel: I had already seen the video, but not the slides. I watch them again

@Peter: From your answer I draw the conclusion that a service and a factory are both singletons. Why having both if they are equal, besides some syntax differences? 

Pawel Kozlowski

unread,
Dec 7, 2012, 7:25:25 AM12/7/12
to ang...@googlegroups.com
Hi!

On Fri, Dec 7, 2012 at 1:21 PM, John Huntjens <johnnyv...@gmail.com> wrote:

> @Peter: From your answer I draw the conclusion that a service and a factory
> are both singletons. Why having both if they are equal, besides some syntax
> differences?

Yes, both will produce singletons. In fact this applies to anything
registered in AngularJS modules - providers, values and constants will
produce only one, single instance.
The service form is not used often but comes handy if you have an
already existing constructor (from a third-party JavaScript code?) and
want to expose it as an AngularJS service.

Cheers,
Pawel

John Huntjens

unread,
Dec 7, 2012, 7:30:18 AM12/7/12
to ang...@googlegroups.com
Thanks Pawel!

Op vrijdag 7 december 2012 13:25:25 UTC+1 schreef Pawel Kozlowski het volgende:
 
Yes, both will produce singletons. In fact this applies to anything
registered in AngularJS modules - providers, values and constants will
produce only one, single instance.
The service form is not used often but comes handy if you have an
already existing constructor (from a third-party JavaScript code?) and
want to expose it as an AngularJS service.

Is there also a way to have a real factory? (e.g. getting a new instance injected in every controller) 

Peter Bacon Darwin

unread,
Dec 7, 2012, 7:32:33 AM12/7/12
to ang...@googlegroups.com
On 7 December 2012 12:25, Pawel Kozlowski <pkozlowski...@gmail.com> wrote:
Yes, both will produce singletons. In fact this applies to anything
registered in AngularJS modules - providers, values and constants will
produce only one, single instance.

Although, of course, controllers defined on modules are not singletons :-)  They are constructors that will be instantiated each time a new one is needed.
 
The service form is not used often but comes handy if you have an
already existing constructor (from a third-party JavaScript code?) and
want to expose it as an AngularJS service.

In particular if you want to code your services as CoffeeScript classes!

-----------

I think people often get confused because it is quite common for people to provide AngularJS services that are factories themselves!  $resource is a classic example.  The $resource object itself is a singleton but we use it to create new resource services, i.e. var BookResource = $resource('Book') will return a new object that we then use as a service in our code.  Since we usually want to have a singleton of BookResource, we wrap this up in yet another AngularJS service to give us the desired effect...

mod.factory('BookResource', function($resource) {
  return $resource('Book');
});

Pawel Kozlowski

unread,
Dec 7, 2012, 7:33:27 AM12/7/12
to ang...@googlegroups.com
Hi!

On Fri, Dec 7, 2012 at 1:30 PM, John Huntjens <johnnyv...@gmail.com> wrote:
> s there also a way to have a real factory? (e.g. getting a new instance
> injected in every controller)

You can always register a factory function and use it to create new
instances of your objects in a controller.
Otherwise there is not standard way of determining is a service should
be singleton or of a new instance should be created on each service
retrieval.
By default things are singletons.

Cheers,
Pawel

--
Question? Send a fiddle
(http://jsfiddle.net/pkozlowski_opensource/Q2NpJ/) or a plunk
(http://plnkr.co/)
Need help with jsFiddle? Check this:
http://pkozlowskios.wordpress.com/2012/08/12/using-jsfiddle-with-angularjs/

Looking for UI widget library for AngularJS? Here you go:
http://angular-ui.github.com/

Peter Bacon Darwin

unread,
Dec 7, 2012, 7:33:32 AM12/7/12
to ang...@googlegroups.com
See my last reply.  You can create a service which is a factory itself and just call this as needed.


--

Pawel Kozlowski

unread,
Dec 7, 2012, 7:36:50 AM12/7/12
to ang...@googlegroups.com
Hey!

On Fri, Dec 7, 2012 at 1:32 PM, Peter Bacon Darwin <pe...@bacondarwin.com> wrote:

> Although, of course, controllers defined on modules are not singletons :-)
> They are constructors that will be instantiated each time a new one is
> needed.

Well, not sure if I would say it like this :-) What is registered for
controllers is they constructor function. This factory function is a
singleton.
It is just the $controller service will retrieve this constructor
function and use it to create new controller instances. So, yes,
controller instances are not singletons but controller's constructors
are.
Just to be precise :-)

Pawel Kozlowski

unread,
Dec 7, 2012, 7:38:02 AM12/7/12
to ang...@googlegroups.com
Hi Peter!

On Fri, Dec 7, 2012 at 1:32 PM, Peter Bacon Darwin <pe...@bacondarwin.com> wrote:
> In particular if you want to code your services as CoffeeScript classes!

This is the part I've never understood really (probably because I'm
not using CS). Could you elaborate on this one a little bit?

Peter Bacon Darwin

unread,
Dec 7, 2012, 7:39:51 AM12/7/12
to ang...@googlegroups.com
CoffeeScipt classes are constructor functions that must be instantiated with the "new" keyword.  Otherwise "this" is not bound properly.


Peter Bacon Darwin

unread,
Dec 7, 2012, 7:41:50 AM12/7/12
to ang...@googlegroups.com
The function you pass to factory, provider & service will never be called more than once.  The function you pass to controller may be called multiple times.


Reply all
Reply to author
Forward
0 new messages