angularjs service, factory and provider

If you've used angularjs for any time then you'll have come across service, factory and provider and probably be confused (at least I was).
Here's a good post about when and why to use each in stackoverflow, especially the answer by allenhwkin

But how do we add prototype functions?
Starting with allenhwkins code I created this plunkr which defines a CarFactory that sets a function on the prototype


.service() and .factory() are application wide singletons

I tested both variations of creating a service using .factory() vs .service()
In both cases, I injected the Service into a controller (standard angular dependency injection) and set a value in the Service using a setter
Then I inject into other controllers including separate pages and the value I previously set is still set for the Service injected
For the standard way you code .factory() and .service(), both are truly application wide singletons. If you set a value its set in the singleton app wide no matter where you inject it

Suffice to say if you want different instances of Service objects then you have to code that yourself; .factory() does not provide that out of the box. I recommend you do that under .factory() and keep .service() as singletons only.

Code factory
    return {
        setReport: function(report) {
            this.report = report;
        },
        getFields: function() {
            console.log("getting fields for report: " + this.report);
        }
    }


Code service
    this.setReport = function(report) {
            this.report = report;
    }
    this.getFields: function() {
            console.log("getting fields for report: " + this.report);
    }


Factory vs Service inside angular.js code

Still trying to 100% understand angular factory vs service, when to use and so forth....is there a meaningful difference or not?

Whats really interesting imo is that when you define a service e.g. .service('MyService') the angularjs code calls the factory() method. Thats right: .factory() and .service() both end up running the same code internally!

In the case of .factory() the function you define in the factory definition is used as a constructor to make new instances
In the case of .service() angular makes a factory function for .service and then calls .factory() passing that.

Here's the angular.js code. See how service() calls factory()

  function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); }

  function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
  }


I set a breakpoint in the angularjs code to check this and thats whats happening alright.

I can use the factoryFn parameter to make a new instance when debugger is stopped at that factory() fn
e.g.   vay myObj = factoryFn;

myObj is an array which is the definition of the factory I defined e.g.

["$rootScope", "$log", function ($rootScope, $log) { // event names var myField; return { Foo: function() {}
};
}]




Provider

"There are five recipe types. The most verbose, but also the most comprehensive one is a Provider recipe. The remaining four recipe types — Value, Factory, Service and Constant — are just syntactic sugar on top of a provider recipe."

you can certainly skip factory and service and just use provider only instead but the use case for provide is if you need to do configuration on the object, from angular:
"You should use the Provider recipe only when you want to expose an API for application-wide configuration that must be made before the application starts."

Comments

Popular posts from this blog

deep dive into Material UI TextField built by mui

angular js protractor e2e cheatsheet

react-router v6.4+ loaders, actions, forms and more