Reputation: 2561
I'm new to Angular and I think I'm using Services incorrectly.
I have three controllers that use data from a REST backend (using Restangular). The endpoint for each is different but the data structure is identical.
After I get the data, I have to do some simple business logic before it can be used in the page, and I want to cache the data locally. But that means I have three controllers with doubled-up code. Not good.
I'd like to centralise that, and let the controllers just ask for a 'version'. I thought I would create an angular Service that wrapped Restangular, and then create three copies of this, each with a different endpoint, and their own state.
But Services are singletons so I guess that's wrong.
Psuedo code...
..MyDataService(..., dataEndpoint)
{
...
var stuff = []
construct() {
this.stuff = Restangular.getData(...)
}
getSmallest() {
return this.stuff.sort(...)
}
getLatest() {
return this.stuff.sort(...)
}
getBiggest() {
return this.stuff.sort(...)
}
}
...RedStuffController()
{
$scope.data = MyService('/things/redstuff/')
}
...BlueStuffController()
{
$scope.data = MyService('/things/blue')
}
...GreenStuffController()
{
$scope.data = MyService('/things/green')
}
What should I be doing?
Upvotes: 2
Views: 600
Reputation: 52867
Services and Factories are singletons - one instance is created and shared among all controllers (and anywhere else its injected). I recommend creating a factory method within your singleton factory/service:
JS
app.factory('MyDataService', function() {
function Stuff(endpoint) {
...
var stuff = []
this.construct() {
stuff = Restangular.getData(...)
}
this.getSmallest() {
return stuff.sort(...)
}
this.getLatest() {
return stuff.sort(...)
}
this.getBiggest() {
return stuff.sort(...)
}
}
return {
get: function(endpoint) {
return new Stuff(endpoint);
}
}
});
Controller
app.controller('RedStuffController', function($scope, MyDataService) {
$scope.data = MyDataService.get('/things/redstuff');
});
app.controller('BlueStuffController', function($scope, MyDataService) {
$scope.data = MyDataService.get('/things/bluestuff');
});
app.controller('GreenStuffController', function($scope, MyDataService) {
$scope.data = MyDataService.get('/things/greenstuff');
});
Upvotes: 2
Reputation: 42669
What you can do is use a factory to create a service constructor and return it. It would look something like this.
app.factory('MyService',function(Restangular) {
function MyService(url) {
this.stuff = Restangular.getData(url)
}
MyService.prototype.getSmallest=function() {
return this.stuff.sort(...)
}
return MyService; //We are not returning service object but service constructor function
});
Now in the controller inject it and you can do
$scope.data = new MyService('/things/green').getSmallest();
Upvotes: 4