0

I have the following module :

angular.module('project.itemServices', ['project.cacheFactory', 'project.dataProvider'])

.run(function() {
        ISvc = new function () {
            this.endpoint = '';
            this.name = 'foo';
            this.items = {};
            this.clean = function () {
                cacheFactory.clear(this.name);
                items = {};
            };
            this._store = null;
            this.populate = function () {
                cacheFactory.look('fetch', this.endpoint, this.name).then(function (data) {
                    this._store(data);
                })
            };
        };
    }
)

.service('catListSvc', function()
{
    this.prototype = ISvc.prototype;
})

.run(function(catListSvc)
{
    console.log(catListSvc.name);
});

I want all my services in this module to inherit from the ISvc object, and then implement it's own _store method, this service is intended for sharing data between controllers.

I don't know how to do this, when trying to console.log(catListSvc.name), undefined comes up.

I tried several things eg. Objects.create(ISvc.prototype), but doesn't work.

Any idea on how to achieve this?

Maxime B
  • 966
  • 1
  • 9
  • 30
  • `this.prototype` doesn't do anything. To setup inheritance you need to set the `prototype` property of the constructor to an object that is attached to the prototype you want to inherit. – Ruan Mendes Jun 03 '16 at 13:15
  • Could you write an example please? I'm confused. – Maxime B Jun 03 '16 at 13:18
  • Unfortunately I can't, angular 1 is not my thing, I'm just explaining where your main problem lies. See http://blog.mgechev.com/2013/12/18/inheritance-services-controllers-in-angularjs/ – Ruan Mendes Jun 03 '16 at 13:26
  • Found kind of an answer here : http://stackoverflow.com/questions/15293943/how-can-i-extend-a-service, but I wonder if I can do it the pure JS way. – Maxime B Jun 03 '16 at 13:27
  • See https://gist.github.com/boneskull/6011707 – Ruan Mendes Jun 03 '16 at 13:29
  • Nice, that's what I was looking for, you can answer if you want. – Maxime B Jun 03 '16 at 13:30
  • @MaximeB It is not possible to apply inheritance to this module only because Angular doesn't differ modules on service level. The example above won't work that good if `baseService` is defined in other file (and often it does). This means that JS modules (`require`/`import`) should be used together with Angular modules, your question doesn't cover these requirements. – Estus Flask Jun 03 '16 at 14:04

1 Answers1

1

The basic pattern for service inheritance that may be spread across several JS files requires only Angular DI is

// service is PascalCased and returns a constructor
function BaseProjectService(...deps...) { ... }

app.value('BaseProjectService', BaseProjectService);

// service is camelCased and returns an instance
app.factory('someProjectService', ['BaseProjectService', ...deps..., function (BaseProjectService, ...deps...) {
  function SomeProjectService(...deps...) { 
    // is a super constuctor, since SomeProjectService has got no own prototype
    this.constructor(...deps); 
    ...
  }
  SomeProjectService.prototype = BaseProjectService.prototype;
  return new SomeProjectService(...deps...);
}]);

The downside is that factory functions and not classes are responsible for deps annotation and injection, this results in WET code

This pattern may become subsequently more complicated when child services need their own prototypes, this is where ES6 classes should be taken into account.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565