1

I tried to implement prototypical inheritance between two AngularJS services and one generic service, but this seems not enough to serve my needs.

I made ChildService, SecondChildService and ParentService.

  • ChildService extends ParentService with prototypical inheritance
  • SecondChildService extends ParentService with prototypical inheritance

ParentService has a method let's call it logIt() that logs property it

  • ChildService implements its own version of it
  • SecondChildService implements its own version of it

Now I consider ParentService as the "base class", and I have a method within ParentService that calls logIt(), that is initialize(). This is only implemented in ParentService

I need to run ChildService.initialize() and see that the it of ChildService gets logged. The same thing with SecondChildService.

Instead the ParentService logs its own version of it. The reason I believe is that prototypical inheritance is a composition implementation rather than real inheritance

Can you please propose a workaround?


Edit:

This is my parent service

angular.module('common').service('parentService', ParentService);
ParentService.$inject = [];

/* @ngInject */
function ParentService() {
  'use strict';
  var vm = this;
  vm.it = "parent";

  vm.initialize = function () {
    vm.logIt();
  };

  vm.logIt = function () {
    console.log(this.it);
  };
}

This is my child service

angular.module('common').service('childService', ChildService);
ChildService.$inject = ['parentService'];

/* @ngInject */
function ChildService(parentService) {
  'use strict';
  var vm = this;
  angular.extend(this, parentService);
  vm.it = "child";
}

And this is what I get in the log when I run childService.initialize()

parent

I am expecting to get child instead

2
  • It would be helpful if you include code that reproduces your problem. Commented Dec 15, 2020 at 3:27
  • I think you misunderstand what angular.extend does. In Javascript the prototype is set with Object.setPrototypeOf not with angular.extend. This is what class B extends A uses under the hood. Commented Dec 17, 2020 at 1:00

2 Answers 2

2

I can't reproduce your problem. Inheritance seems to work correctly in the following example:

class Main {
    do_it() {
        console.log("Main do_it");
        this.it();
    }
    it() {
        console.log("Main it executed");
    }
}

class A extends Main {
    it() {
        console.log("A it executed");
    }
}

var a = new A;
a.do_it();
console.log("Done");

The do_it method that is defined in the Main class correctly calls the it method of the extended class which has overridden the it method of the parent class.

Sign up to request clarification or add additional context in comments.

Comments

0

The problem is in ParentService. I am using vm.logIt, while I should be using this.logIt in order to get the it from the child service scope. Contrary to standard inheritance, it seems that in prototypical inheritance the logIt() function exists twice, once in the ParentService and once in the ChildService (inherited from parent). With this.logIt() you can call it from the child and it actually gets the it from the child, while with vm.logIt() you call it from the parent where it gets the it from. It is a matter of scope.

This is the correct implementation of ParentService:

angular.module('common').service('parentService', ParentService);
ParentService.$inject = [];

/* @ngInject */
function ParentService() {
  'use strict';
  var vm = this;
  vm.it = "parent";

  vm.initialize = function () {
    this.logIt(); // <-- this changed
  };

  vm.logIt = function () {
    console.log(this.it);
  };
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.