Reputation: 12035
So I have a tree helper object in my angular app that provides a bunch of useful functions for dealing with the many tree structures in the app. This is provided by a factory, so each time some controller (or whatever) asks for a tree helper, it gets its own copy:
angular.module('MainApp').factory('TreeHelperFactory',
function ($http, $q, $filter, DataService) {
var treeHelper = new function ($http, $q, $filter, DataService) {
...
code
...
})
Now I have a category service that provides various category-related functions, including returning a tree of categories and providing ways to manipulate that tree. So thinking like an OO developer, I reckon that the category service is really like a subclass of my tree helper, so I inject a tree helper instance and then attempt to extend that instance with category-specific functions, naively like this:
angular.module('MainApp').provider('CategoryService',
function() {
this.$get = function ($http, $q, $filter, DataService, TreeHelperFactory) {
var catService = TreeHelperFactory;
catService.listCategories = function() {...}
catService.deleteCategory = function(id) {...}
... more code...
return catService;
}
}
);
But this doesn't work. The new properties are not visible when I try to invoke them later, only the tree helper properties of the original factory object. What am I missing and how do I achieve this?
Upvotes: 1
Views: 101
Reputation: 32377
Services in angular.js are singletons, which means each time you inject a service it returns the exact same object, you cannot force it to return a new object each time it is injected.
What you can do is to create a Class
function, for example:
angular.module('MainApp')
.factory('TreeHelperFactory',
function ($http, $q, $filter, DataService) {
/**
* TreeHelper constructor
* @class
*/
function TreeHelper() { /* this.init(); */ }
/**
* TreeHelper static class method
*/
TreeHelper.list = function() { /* ... */ };
/**
* TreeHelper instance method
*/
TreeHelper.prototype.init = function() { /*...*/ };
/**
* Returns the class
*/
return TreeHelper;
})
Now you can inject it, instantiate an object and extend it like so:
.factory('CategoryService', function (TreeHelperFactory) {
var catService = new TreeHelperFactory();
catService.listCategories = function() { /*...*/ };
catService.deleteCategory = function(id) { /*...*/ };
return catService;
});
You can also use javascript prototypical inheritance but I think it's an overkill for most cases so keep it simple if you can.
Upvotes: 1
Reputation: 3374
Helper that depends on Angular services is a bad smell for me - almost like its status is more than a helper and it has a service or two in it. Would you be able to rethink this through restructuring their roles and responsibilities?
Upvotes: 0