breezejs: dynamically switching between OData and WebAPI - angularjs

I'm facing a bit of a tricky situation here. I have two services that my application needs to access to. One is a pure ODATA service and the other is a WebAPI (with Breeze controller) service.
My application is designed around the AngularJS modules and breeze is injected into two differerent single-instance services :
angular.module('domiciliations.services').
factory('domiciliationService', function (breeze) {
breeze.config.initializeAdapterInstance("modelLibrary", "backingStore", true);
//more initialization goes here
//then query methods go here
}
and
angular.module('person.services').
factory('personService', function (breeze) {
breeze.config.initializeAdapterInstances({ "dataService": "OData" });
//more initialization goes here
//then query methods go here
}
Now obviously the problem is that once the person service has been instanciated, the domiciliations service then uses OData because the config was overwritten.
So, what is the general approach for tackling this issue ? Is there a way to isolate the config ?
So far the only way I can think of, is to call the initializeAdapterinstances method each time a query method is called, which is not really desirable.
EDIT
As per Jay's recommandation I'm now using DataService. I'm having an error though in ctor.resolve at the line:
ds.jsonResultsAdapter = ds.jsonResultsAdapter || ds.adapterInstance.jsonResultsAdapter;
ds.adapterInstance is null, therefore this throws an exception. But I don't understand why it's null.
Here's what I've done:
var service = new breeze.DataService({
serviceName: 'http://localhost:16361/api/mandates',
adapterName: 'WebApi'
});
var manager = new breeze.EntityManager({ dataService: service });
//this is the line causing the later exception:
manager.fetchMetadata().then(function () { ... }
Did I forget to do something ?

Good question!
The initializeAdapterInstance method is really intended to setup the 'default' adapters.
If you need to have multiple adapters and apply them on a per query basis then see the DataService documentation especially the 'adapterName' property in the ctor. You can have two DataServices, one for OData and one for WebApi. You can then use either for any query via the EntityQuery.using method.
var odataDataService = new DataService({
serviceName: "Foo",
adapterName: "OData"
});
var webApiDataService = new DataService({
serviceName: "Bar",
adapterName: "WebApi"
});
var query1 = EntityQuery.from(...).where(...);
var query2 = EntityQuery.from(...).where(...);
entityManager.executeQuery(query1.using(odataDataService)).then(...)
entityManager.executeQuery(query2.using(webApiDataService)).then(...)

Related

Reopening PouchDB in a second Angular factory results in Pouch not using SQLite plugin

I'm writing an Ionic app that uses PouchDB and the SQLite plugin. I have a factory responsible for opening the db and exposing some methods for getting records etc:
.factory('PouchdbFactory', ['$q', function ($q) {
var db,
codes = [];
var initDB = function() {
db = new PouchDB('codes', {adapter: 'websql', auto_compaction: true, location: 2}); // location should be 2
// Listen for changes on the database
db.changes({ live: true, since: 'now', include_docs: true}).on('change', onDatabaseChange);
db.info().then(console.log.bind(console));
}
...etc...
And another factory that returns methods that are used to periodically get the records and change them.
.factory('OtpFactory', ['$rootScope', '$interval', 'PouchdbFactory', function($rootScope, $interval, PouchdbFactory) {
var otpCodes,
globalTimerPromise,
totpObj = new TOTP();
// this breaks sqllite plugin (db.info().then(console.log.bind(console)); returns sqlite_plugin: false )
PouchdbFactory.initDB();
PouchdbFactory.getAllCodes().then(function(codes) {
otpCodes = codes;
});
Calling PouchdbFactory.initDB(); in the second factory results in pouch not using the SQLite plugin (db.info().then(console.log.bind(console)); returns sqlite_plugin: false).
I'm still learning Angular, so perhaps this is not the way to structure it. I could move the db creation into $rootscope so the database can be access in all factories but I don't understand why calling PouchdbFactory.initDB(); a second time means no sqlite_plugin.
Any ideas?
Not that it's the reason for the error, but I would rather just return the db instance if it's initialized. Try a guard clause in init that's checks db has been initialized - if it has the return db straight away, if not then continue to initialize it.

Angular - reusing code (service or controller)

I'm using Angular to develop commenting functionality for a web app.
Currently there are two sections in the application were a user can comment:
Category
Product
About 90% of the commenting functionality is the same for both sections and as such I would like to make this reusable - i.e write some service or controller that I can reference/use as a base.
So far, my research seems to point to using a factory service but unfortunately this doesn't seem to work (I've spent the whole day running through various tutorials).
It is quite possible that I am over thinking this and making it far too complicated but I honestly don't know which way to turn anymore.
Herewith a quick and dirty overview of what I have so far:
HTML view for the category
Controller for the category (receives data from service and posts data to service in order to bind data to model)
Service for the category (retrieve and stores all the necessary
data)
The product uses the same logic and a lot of the code in the service and controller will be duplicated.
I've merged the two services into one service successfully but I'm having trouble doing the same for the controller.
Do I:
Write a base controller that will communicate with the above mentioned service and that will hookup with the two existing controllers
OR
Write a factory/provider service that hooks up to the two existing controllers as well as the above mentioned service.
If you go the route of using a factory, you could put all the common functionality into its return object and reference that from your controllers.
Factory
angular.module('myModule').factory('CommonFunctions', function(){
return {
foo : foo,
bar : bar
}
function foo(){
console.log('foo');
};
function bar (){
console.log('bar');
};
}
Controller
angular.module('myModule')
.controller('myController', ['CommonFunctions', function(CommonFunctions) {
var vm = this;
vm.foo = CommonFunctions.foo();
vm.bar = CommonFunctions.bar();
}
angular's separation of service types ie:
for specific values
constant
value
(constant for specific values needed before other services are created)
for functions
factory
service
provider
(provider for specific instances when you need a services before other services are created, usually taking advantage of constants)
allow the ability to share data and ways to process that data between controllers and or directives, anything that can be a value can also be a constant, the only difference there being where they can be injected. Similarly any service can be rewritten to a factory or a provider, it is more your specific use case / what your more comfortable writing that would determine which to use, but really the best way to think about it is if you have a value that needs to be shared but is not needed inside angular.module.config then use value, otherwise use constant, now if you have a single function that you want to share, (maybe it processes that value in some way or maybe it just does something else) you should write it as a factory, then when you have a few of those factory's that deal with either that value, or anything else, you can combine them into a service or configure and combine them using a provider. here is a simple example (note i am using the recommended syntax for writing angular services):
'use strict';
var app = angular.module('test.app',[]);
app.constant('configureableValue',{defaultValue:55});
app.value('editableValue',{defaultValue:100,editedValue:null});
app.provider('configureValue',configureValueProvider);
configureValueProvider.$inject - ['configureableValue'];
function configureValueProvider(configureableValue){
var defaultVal = configureableValue.defaultValue,
originalVal = defaultVal;
return {
getValue:getValue,
setValue:setValue,
resetValue:resetValue,
'$get':providerFunc
};
function getValue(){
return defaultVal;
}
function setValue(val){
defaultVal = val;
}
function providerFunc(){
return {
get:function(){ return getValue(); },
reset:function(){ resetValue(); }
};
}
function resetValue(){
defaultVal = originalVal
}
}
// this factory is an example of a single function service, this should almost always be defined as a factory
app.factory('getEditableValue',getEditableValue);
getEditableValue.$inject = ['editableValue'];
function getEditableValue(editableValue){
return function(){
return editableValue.editedValue ? editableValue.editedValue : editableValue.defaultValue;
};
}
// same with this one
app.factory('setEditableValue',setEditableValue);
setEditableValue.$inject = ['editableValue'];
function setEditableValue(editableValue){
return function(val){
editableValue.editedValue = val;
}
}
// now this is an example of a service service collecting the factorys for an object with all the related behavior we need
app.service('editableService',editableService);
editableService.$inject = ['getEditableValue','setEditableValue'];
function editableService(getEditableValue,setEditableValue){
var self = this;
self.setVal = setEditableValue;
self.getVal = getEditableValue;
}
app.config(appConfig);
appConfig.$inject = ['configureValueProvider'];
function appConfig(configureValueProvider){
configureValueProvider.setValue('i changed '+ configureValueProvider.getValue() +' to this!!!!');
}
app.run(appRun);
appRun.$inject = ['configureValue','editableService'];
function appRun(configureValue,editableService){
console.log('before editing: ',editableService.getVal());
editableService.setVal('changed!!!');
console.log('after editing: ',editableService.getVal());
console.log('we changed this in the config func: ',configureValue.get());
configureValue.reset();
console.log('and now its back to the original value: ',configureValue.get());
}
i know thats a lot for a simple example, but there are a lot of features provided by angular, and many ways to use them, hopefully this helps.

SignalR: How to add client call after the hub is started?

First off, I just started trying to add SignalR 2 to my existing Angular SPA project.
I have a main controller which starts the hub right away that is feeding some messages to the client. Inside, I have several sub pages and each could subscribe to a different hub for services. The problems is that the client doesn't receive message because it is hooked up after the hub is already started in the main controller.
As a test, if I comment out the hub start in the main controller, the one in the sub controller works fine.
From what I read, it is by design that you have to hook up all client calls before starting the hub. I don't understand...if it is a service, I should be able to subscribe or unsubscribe anytime after the hub is started. Why not? How to workaround?
Because no response in the 12 hours (which is quite unusual in so), I had to dig around myself. I think, I was misled by the answers from SO on related questions that you have to subscribe all client call before starting the connection, as mentioned e.g. here. I found in Hubs API Guide, one section says
Define method on client (without the generated proxy, or when adding
after calling the start method)
So, it is possible to add client method after connection is started. The trick is to use so-called "without the generated proxy". That limitation is for "with generated proxy".
The following is my working example taken from SignalR get started tutorial.
This is the main controller using "with generated proxy":
$.connection.statusHub.client.updateStatus = function (status) {
$scope.status = status;
$scope.$apply();
}
$.connection.hub.start();
This is in a subcontroller using "without generated proxy":
var connection = $.hubConnection();
var proxy = connection.createHubProxy('stockTickerHub');
proxy.on('updateStockPrice', function (stock) {
var st = $scope.stocks.firstOfKey(stock.symbol, 'symbol');
st.lastPrice = stock.lastPrice;
$scope.$apply();
});
var hub = $.connection.stockTickerHub;
connection.start().done(function () {
hub.server.getAllStocks().done(function (stocks) {
$scope.stocks = stocks;
});
});
Note that it doesn't work if I use "with generated proxy" in the subcontroller like this:
var hub = $.connection.stockTickerHub;
hub.client.updateStockPrice = function (stock) {
var st = $scope.stocks.firstOfKey(stock.symbol, 'symbol');
st.lastPrice = stock.lastPrice;
$scope.$apply();
};
$.connection.hub.start().done(function () {
hub.server.getAllStocks().done(function (stocks) {
$scope.stocks = stocks;
});
});
To prove the limitation of "with generated proxy" mode, this code works if I comment out the one in the main controller.
By the way, I was so confused by the term with or without generated proxy in the Guide, and in both cases, it is still called xxxProxy. Can't they find a better name? Or somebody has an explanation?

Breeze.JS to use angular.js http

I am trying to make Breeze.JS to make use of angular's http service for ajax calls. I followed the the docs (http://www.breezejs.com/documentation/customizing-ajax) and applied it. However it doesn't work.
Further more when I checked breeze source code I saw the following:
fn.executeQuery = function (mappingContext) {
var deferred = Q.defer();
var url = mappingContext.getUrl();
OData.read({
requestUri: url,
headers: { "DataServiceVersion": "2.0" }
},
function (data, response) {
var inlineCount;
if (data.__count) {
// OData can return data.__count as a string
inlineCount = parseInt(data.__count, 10);
}
return deferred.resolve({ results: data.results, inlineCount: inlineCount });
},
function (error) {
return deferred.reject(createError(error, url));
}
);
return deferred.promise;
};
It simply calls OData.read without doing anything about http service. Thus OData makes use of builtin ajax. I don't understand with above code, how it is possible to customize ajax of Breeeze.JS
The problem is that the Breeze OData path does NOT use the Breeze Ajax adapter. Changing the Breeze Ajax Adapter (as the "Breeze Angular Service" does) won't help.
At the moment, both the "OData" and "webApiOData" DataService Adapters delegate to the 3rd party datajs library for AJAX services (and for other OData-related support).
You could replace its odata.defaultHttpClient with a version of your own based on $http. That's not a trivial task. Look here for the source code; it's roughly 160 lines.
I suppose we could write one. It hasn't been a priority.
Until somebody does it or we abandon datajs (not soon if ever), you're stuck with the datajs ajax.
Sorry about that.
p.s. Just about everyone who talks to OData data sources uses the datajs library. Maybe you can talk to the authors of that library and try to get them to support$http.
Quick and dirty hack to simulate $http service
I ran into this issue today. Since the external datajs AJAX methods are used rather than Angular's $http service (as explained by Ward), Breeze queries do not trigger a digest and the models do not get updated.
As with any external-to-angular changes, the simple solution is to wrap any assignments from your queries in a $scope.$apply() function. However, this will quickly clutter up your app so it's a bad idea.
I came up with a quick and dirty hack that so far seems to work well:
I have a dataContextservice which encapsulates all my Breeze queries and exposes methods like getCustomers(), getProducts() etc (inspired by the example on the Breeze site).
When any of these data-access methods completes (ie the promise resolves), I call a triggerAngularDigest() method.
This method simple calls $rootScope.$apply() inside a $timeout().
The $timeout() causes Angular to run the digest on the next tick, i.e. after the data from your Breeze query has been assigned to your models.
All your models update just like when you use $http, no need to call $apply() in your controllers.
Simplified version:
function dataContext($rootScope, $timeout, breeze) {
// config of entity manager etc snipped
return {
getCustomers: function () {
return breeze.EntityQuery.from('Customers')
.using(manager)
.execute()
.then(function(data) {
triggerAngularDigest(); // <-- this is the key
return data;
});
}
};
function triggerAngularDigest() {
$timeout(function() {
$rootScope.$apply();
}, 0);
}
}
myApp.factory('dataContext', dataContext);
Then:
// some controller in your app
dataContext.getCustomers().then(function(data) {
scope.customers = data;
});

AngularJS : When to use service instead of factory

Please bear with me here. I know there are other answers such as:
AngularJS: Service vs provider vs factory
However I still can't figure out when you'd use service over factory.
From what I can tell factory is commonly used to create "common" functions that can be called by multiple Controllers: Creating common controller functions
The Angular docs seem to prefer factory over service. They even refer to "service" when they use factory which is even more confusing! http://docs.angularjs.org/guide/dev_guide.services.creating_services
So when would one use service?
Is there something that is only possible or much easier done with service?
Is there anything different that goes on behind the scenes? Performance/memory differences?
Here's an example. Other than the method of declaration, they seem identical and I can't figure out why I'd do one vs the other. http://jsfiddle.net/uEpkE/
Update: From Thomas' answer it seems to imply that service is for simpler logic and factory for more complex logic with private methods, so I updated the fiddle code below and it seems that both are able to support private functions?
myApp.factory('fooFactory', function() {
var fooVar;
var addHi = function(foo){ fooVar = 'Hi '+foo; }
return {
setFoobar: function(foo){
addHi(foo);
},
getFoobar:function(){
return fooVar;
}
};
});
myApp.service('fooService', function() {
var fooVar;
var addHi = function(foo){ fooVar = 'Hi '+foo;}
this.setFoobar = function(foo){
addHi(foo);
}
this.getFoobar = function(){
return fooVar;
}
});
function MyCtrl($scope, fooService, fooFactory) {
fooFactory.setFoobar("fooFactory");
fooService.setFoobar("fooService");
//foobars = "Hi fooFactory, Hi fooService"
$scope.foobars = [
fooFactory.getFoobar(),
fooService.getFoobar()
];
}
Explanation
You got different things here:
First:
If you use a service you will get the instance of a function ("this"
keyword).
If you use a factory you will get the value that is returned by
invoking the function reference (the return statement in factory).
ref: angular.service vs angular.factory
Second:
Keep in mind all providers in AngularJS (value, constant, services, factories) are singletons!
Third:
Using one or the other (service or factory) is about code style.
But, the common way in AngularJS is to use factory.
Why ?
Because "The factory method is the most common way of getting objects into AngularJS dependency injection system. It is very flexible and can contain sophisticated creation logic. Since factories are regular functions, we can also take advantage of a new lexical scope to simulate "private" variables. This is very useful as we can hide implementation details of a given service."
(ref: http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821).
Usage
Service : Could be useful for sharing utility functions that are useful to invoke by simply appending () to the injected function reference. Could also be run with injectedArg.call(this) or similar.
Factory : Could be useful for returning a ‘class’ function that can then be new`ed to create instances.
So, use a factory when you have complex logic in your service and you don't want expose this complexity.
In other cases if you want to return an instance of a service just use service.
But you'll see with time that you'll use factory in 80% of cases I think.
For more details: http://blog.manishchhabra.com/2013/09/angularjs-service-vs-factory-with-example/
UPDATE :
Excellent post here :
http://iffycan.blogspot.com.ar/2013/05/angular-service-or-factory.html
"If you want your function to be called like a normal function, use
factory. If you want your function to be instantiated with the new
operator, use service. If you don't know the difference, use factory."
UPDATE :
AngularJS team does his work and give an explanation:
http://docs.angularjs.org/guide/providers
And from this page :
"Factory and Service are the most commonly used recipes. The only difference between them is that Service recipe works better for objects of custom type, while Factory can produce JavaScript primitives and functions."
allernhwkim originally posted an answer on this question linking to his blog, however a moderator deleted it. It's the only post I've found which doesn't just tell you how to do the same thing with service, provider and factory, but also tells you what you can do with a provider that you can't with a factory, and with a factory that you can't with a service.
Directly from his blog:
app.service('CarService', function() {
this.dealer="Bad";
this.numCylinder = 4;
});
app.factory('CarFactory', function() {
return function(numCylinder) {
this.dealer="Bad";
this.numCylinder = numCylinder
};
});
app.provider('CarProvider', function() {
this.dealerName = 'Bad';
this.$get = function() {
return function(numCylinder) {
this.numCylinder = numCylinder;
this.dealer = this.dealerName;
}
};
this.setDealerName = function(str) {
this.dealerName = str;
}
});
This shows how the CarService will always a produce a car with 4 cylinders, you can't change it for individual cars. Whereas CarFactory returns a function so you can do new CarFactory in your controller, passing in a number of cylinders specific to that car. You can't do new CarService because CarService is an object not a function.
The reason factories don't work like this:
app.factory('CarFactory', function(numCylinder) {
this.dealer="Bad";
this.numCylinder = numCylinder
});
And automatically return a function for you to instantiate, is because then you can't do this (add things to the prototype/etc):
app.factory('CarFactory', function() {
function Car(numCylinder) {
this.dealer="Bad";
this.numCylinder = numCylinder
};
Car.prototype.breakCylinder = function() {
this.numCylinder -= 1;
};
return Car;
});
See how it is literally a factory producing a car.
The conclusion from his blog is pretty good:
In conclusion,
---------------------------------------------------
| Provider| Singleton| Instantiable | Configurable|
---------------------------------------------------
| Factory | Yes | Yes | No |
---------------------------------------------------
| Service | Yes | No | No |
---------------------------------------------------
| Provider| Yes | Yes | Yes |
---------------------------------------------------
Use Service when you need just a simple object such as a Hash, for
example {foo;1, bar:2} It’s easy to code, but you cannot instantiate
it.
Use Factory when you need to instantiate an object, i.e new
Customer(), new Comment(), etc.
Use Provider when you need to configure it. i.e. test url, QA url,
production url.
If you find you're just returning an object in factory you should probably use service.
Don't do this:
app.factory('CarFactory', function() {
return {
numCylinder: 4
};
});
Use service instead:
app.service('CarService', function() {
this.numCylinder = 4;
});
The concept for all these providers is much simpler than it initially appears. If you dissect a provider you and pull out the different parts it becomes very clear.
To put it simply each one of these providers is a specialized version of the other, in this order: provider > factory > value / constant / service.
So long the provider does what you can you can use the provider further down the chain which would result in writing less code. If it doesn't accomplish what you want you can go up the chain and you'll just have to write more code.
This image illustrates what I mean, in this image you will see the code for a provider, with the portions highlighted showing you which portions of the provider could be used to create a factory, value, etc instead.
(source: simplygoodcode.com)
For more details and examples from the blog post where I got the image from go to: http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
Both the factory and the service result in singleton objects which are able to be configured by providers and injected into controllers and run blocks. From the point of view of the injectee, there is absolutely no difference whether the object came from a factory or a service.
So, when to use a factory, and when to use a service? It boils down to your coding preference, and nothing else. If you like the modular JS pattern then go for the factory. If you like the constructor function ("class") style then go for the service. Note that both styles support private members.
The advantage of the service might be that it's more intuitive from the OOP point of view: create a "class", and, in conjunction with a provider, reuse the same code across modules, and vary the behavior of the instantiated objects simply by supplying different parameters to the constructor in a config block.
There is nothing a Factory cannot do or does better in comparison with a Service. And vice verse. Factory just seems to be more popular. The reason for that is its convenience in handling private/public members. Service would be more clumsy in this regard.
When coding a Service you tend to make your object members public via “this” keyword and may suddenly find out that those public members are not visible to private methods (ie inner functions).
var Service = function(){
//public
this.age = 13;
//private
function getAge(){
return this.age; //private does not see public
}
console.log("age: " + getAge());
};
var s = new Service(); //prints 'age: undefined'
Angular uses the “new” keyword to create a service for you, so the instance Angular passes to the controller will have the same drawback.
Of course you may overcome the problem by using this/that:
var Service = function(){
var that = this;
//public
this.age = 13;
//private
function getAge(){
return that.age;
}
console.log("age: " + getAge());
};
var s = new Service();// prints 'age: 13'
But with a large Service constant this\that-ing would make the code poorly readable.
Moreover, the Service prototypes will not see private members – only public will be available to them:
var Service = function(){
var name = "George";
};
Service.prototype.getName = function(){
return this.name; //will not see a private member
};
var s = new Service();
console.log("name: " + s.getName());//prints 'name: undefined'
Summing it up, using Factory is more convenient. As Factory does not have these drawbacks. I would recommend using it by default.
Even when they say that all services and factories are singleton, I don't agree 100 percent with that. I would say that factories are not singletons and this is the point of my answer. I would really think about the name that defines every component(Service/Factory), I mean:
A factory because is not a singleton, you can create as many as you want when you inject, so it works like a factory of objects. You can create a factory of an entity of your domain and work more comfortably with this objects which could be like an object of your model. When you retrieve several objects you can map them in this objects and it can act kind of another layer between the DDBB and the AngularJs model.You can add methods to the objects so you oriented to objects a little bit more your AngularJs App.
Meanwhile a service is a singleton, so we can only create 1 of a kind, maybe not create but we have only 1 instance when we inject in a controller, so a service provides more like a common service(rest calls,functionality.. ) to the controllers.
Conceptually you can think like services provide a service, factories can create multiple instances(objects) of a class
Services
Syntax: module.service( 'serviceName', function );
Result: When declaring serviceName as an injectable argument you will be provided the actual function reference passed to module.service.
Usage: Could be useful for sharing utility functions that are useful to invoke by simply appending () to the injected function reference. Could also be run with injectedArg.call( this ) or similar.
Factories
Syntax: module.factory( 'factoryName', function );
Result: When declaring factoryName as an injectable argument you will be provided the value that is returned by invoking the function reference passed to module.factory.
Usage: Could be useful for returning a 'class' function that can then be new'ed to create instances.
Providers
Syntax: module.provider( 'providerName', function );
Result: When declaring providerName as an injectable argument you will be provided the value that is returned by invoking the $get method of the function reference passed to module.provider.
Usage: Could be useful for returning a 'class' function that can then be new'ed to create instances but that requires some sort of configuration before being injected. Perhaps useful for classes that are reusable across projects? Still kind of hazy on this one.
Can use both the way you want : whether create object or just to access functions from both
You can create new object from service
app.service('carservice', function() {
this.model = function(){
this.name = Math.random(22222);
this.price = 1000;
this.colour = 'green';
this.manufacturer = 'bmw';
}
});
.controller('carcontroller', function ($scope,carservice) {
$scope = new carservice.model();
})
Note :
service by default returns object and not constructor function .
So that's why constructor function is set to this.model property.
Due to this service will return object,but but but inside that object will be constructor function which will be use to create new object;
You can create new object from factory
app.factory('carfactory', function() {
var model = function(){
this.name = Math.random(22222);
this.price = 1000;
this.colour = 'green';
this.manufacturer = 'bmw';
}
return model;
});
.controller('carcontroller', function ($scope,carfactory) {
$scope = new carfactory();
})
Note :
factory by default returns constructor function and not object .
So that's why new object can be created with constructor function.
Create service for just accessing simple functions
app.service('carservice', function () {
this.createCar = function () {
console.log('createCar');
};
this.deleteCar = function () {
console.log('deleteCar');
};
});
.controller('MyService', function ($scope,carservice) {
carservice.createCar()
})
Create factory for just accessing simple functions
app.factory('carfactory', function () {
var obj = {}
obj.createCar = function () {
console.log('createCar');
};
obj.deleteCar = function () {
console.log('deleteCar');
};
});
.controller('MyService', function ($scope,carfactory) {
carfactory.createCar()
})
Conclusion :
you can use both the way you want whether to create new object or
just to access simple functions
There won't be any performance hit , using one over the other
Both are singleton objects and only one instance is created per app.
Being only one instance every where their reference is passed.
In angular documentation factory is called service and also service is called service.
Factory and Service are the most commonly used method. The only difference between them is that the Service method works better for objects that need inheritance hierarchy, while the Factory can produce JavaScript primitives and functions.
The Provider function is the core method and all the other ones are just syntactic sugar on it. You need it only if you are building a reusable piece of code that needs global configuration.
There are five methods to create services: Value, Factory, Service, Provider and Constant. You can learn more about this here angular service, this article explain all this methods with practical demo examples.
.

Resources