Reputation: 870
Angular JS conceptual overview. View-independent business logic: Services (heading). The description says - moving view-independent logic from the controller into a service, yet the code says factory. What am I missing here?
angular.module('finance2', [])
.factory('currencyConverter', function() {
var currencies = ['USD', 'EUR', 'CNY'];
Link to the resource
Upvotes: 2
Views: 46
Reputation: 8455
Coming from a Java
background, I really like the concept of angular factories; we get to mimic POJOs here to an extent. I get to attach meaningful methods and execute logic that's all self-contained within the model itself. Whereas for services, I tend to treat those as I'd treat a service on the server-side, simply for fetching data.
For instance, if we were building a Twitter clone of some sort, for the tweet stream, I'd have a TweetSteamFactory
that internally fetches data using TweetService
to get the latest tweets. Maybe my factory has a getNextPage()
method, which is bound to an ngClick
somewhere - when fired, it of course makes its call with TweetService
.
At any rate, I do see a pretty clear distinction between services and factories, although my understanding could be misguided.
http://plnkr.co/edit/SqPf212nE5GrSPcZdo5K
Controller
app.controller('MyController', function(FoobarFactory) {
FoobarFactory()
done(function(factory) {
var factory = factory;
$scope.data = factory.getData();
$scope.baz = factory.getBaz();
})
});
Factory
app.factory('FoobarFactory', ['MyService', function(MyService) {
function Foobar() {}; // Empty constructor
angular.extend(Foobar.prototype, {
_init: function() {
var deferred = $.Deferred();
var foobar = this;
this.baz = true;
this.data = undefined;
MyService.getData()
.done(function(data) {
foobar.data = data;
deferred.resolve(foobar);
})
deferred.resolve();
return deferred.promise();
},
getBaz: function() {
return this.baz;
},
getData: function() {
return this.data;
}
});
return function () {
var deferred = $.Deferred();
var foobar = new Foobar();
foobar._init()
.done(function() {
deferred.resolve(foobar);
})
.fail(function(error) {
deferred.reject(error);
});
return deferred.promise();
};
}]);
Upvotes: 1
Reputation: 1661
The factory method ('recipe') is a way of creating a 'Service'.
You can also create 'Services' with the service, constant, value, and provider recipes ('methods').
However you do it, you'll end up instantiating an object that is conceptually a 'Service'.
It's been acknowledged widely that this is a confusing aspect of Angular. See this classic Stackoverlow question.
The developer guide does a good job of clarifying these concepts too:
Each web application you build is composed of objects that collaborate to get stuff done. These objects need to be instantiated and wired together for the app to work. In Angular apps most of these objects are instantiated and wired together automatically by the injector service.
The injector creates two types of objects, services and specialized objects.
Services are objects whose API is defined by the developer writing the service.
Specialized objects conform to a specific Angular framework API. These objects are one of controllers, directives, filters or animations.
The injector needs to know how to create these objects. You tell it by registering a "recipe" for creating your object with the injector. 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.
Upvotes: 1