1

I have 2 classes, Class A and ClassB. Class B extends Class A so that I can access the instances and services of Class A. Class B has some functions which I will use in Class A. When I implemented this, circular Dependency error showed up and now I get a browser error saying:

"tslib.es6.js:25 Uncaught TypeError: Object prototype may only be an Object or null: undefined".


import { BuyerCardComponent} from './buyer-card.component'

export class BuyerCardExtended extends BuyerCardComponent{
  func a(){
    do_something;
  }
}

import { BuyerCardExtended } from './buyer-card-extended'

class BuyerCardComponent {
constructor(private buyerCardExtended: BuyerCardExtended){}
  func b(){
    this.buyerCardExtended.a()
  }
}

WARNING in Circular dependency detected: src/app/components/buyer/products/buyer-card/buyer-card.component.ts -> src/app/components/buyer/products/buyer-card/buyer-card-extended.ts -> src/app/components/buyer/products/buyer-card/buyer-card.component.ts

Browser :

"tslib.es6.js:25 Uncaught TypeError: Object prototype may only be an Object or null: undefined"

Prashant Pimpale
  • 10,349
  • 9
  • 44
  • 84
karthi keyan
  • 53
  • 2
  • 7
  • Put them in the same file – Bunyamin Coskuner Aug 01 '19 at 07:09
  • 1
    "*Class B extends Class A so that I can access the instances and services of Class A*" sounds like you are using inheritance for code sharing. Remember: [composition over inheritance](https://en.wikipedia.org/wiki/Composition_over_inheritance) - if you just want to share *functionality*, then modularise it and include it. Extend other objects to do this pollutes your architecture and leads to design decisions you might regret later. – VLAZ Aug 01 '19 at 07:12
  • Separate the logic both classes share into a third class and what is different into each. You cannot have the extended class as dependency in the other. How would a compiler try to dissolve that? He would need to create a BuyerCardExtended in order to create the BuyerCardComponent, but also needs the BuyerCardComponent for the BuyerCardExtended. You have created a chicken and egg problem. – Erbsenkoenig Aug 01 '19 at 07:12
  • Actually upon reading the very next sentence of yours (hadn't when I wrote my first comment) that's a perfect example of *why* inheritance for code sharing is wrong: "*Class B has some functions which I will use in Class A*" You need to have `A extends B` and `B extends A` for it to work...which *doesn't* work at all on conceptual level or in terms of implementing it. – VLAZ Aug 01 '19 at 07:14
  • @BunyaminCoskuner, they were in the same file before and the logic was inside one big function which increased the cyclomatic complexity to 20+ (Coding standard restricts to 20). Hence, the decision to split the logic – karthi keyan Aug 01 '19 at 07:18

2 Answers2

0

The main reason behind this scenario is this sequence: When you execute Class A, it automatically imports Class B. Inside Class B you import Class A which automatically imports Class B once again. This sequence happens again and again and eventually cause circular dependency.

First solution is to create another Class and import all dependencies into that. Or if you just want to share some functions and variables between the two classes, I suggest you to use a shared service and declare all functions in that. Then, import the service into your components or Classes.

  • So, I will create another class and import the core dependencies into this class and in other classes, I'll instantiate this base class & access these dependencies ? – karthi keyan Aug 01 '19 at 07:42
  • It really depends on what your goals are, but in this particular case what you said will do the work. – Puria Rad Jahanbani Aug 01 '19 at 11:18
0

If you want to call a child class method from a parent class, use @ViewChild decorator.

import { BuyerCardExtended } from './buyer-card-extended'

class BuyerCardComponent implements AfterViewInit {
@ViewChild(BuyerCardExtended) childCmp : BuyerCardExtended;
constructor(){}
ngAfterViewInit(){
  func b(){
    this.childCmp.a(); }
  }
}

See also this stackoverflow thread

M M
  • 655
  • 1
  • 7
  • 16
  • BuyerCardExtended extends this class, won't it be a circular dependency again – karthi keyan Aug 01 '19 at 09:11
  • It shouldn't. ViewChild does not instantiate an object of the class. It creates a View Query. I believe it should work. Do give it a try and let us know. – M M Aug 01 '19 at 11:31