2

My head is going around in circles on this one.

I want to create classes to represent data returned from the back end in Angular (not AngularJS).

I have two top level classes Variation and Reallocation. Both are types of base class Adjustment. Therefore both Variation and Reallocation extend Adjustment. Most of the class definition is in the Adjustment class with only small, but important, differences between the two derived classes.

It seems to make sense to use the Adjustment class to handle most of the communication with the back-end. That is, say I want to get a Variation. I should be able to pass an id to a getAdjustment method of Variation and have it return an instance of Variation populated with data from the server.

So far that all makes logical sense to me and I CAN get it to work.

The problem is that somewhere along the line I have to use a service to get data from the backend. I happen to be using AngularFirestore to get data.

So, in my Adjustment class I have to include a constructor something along the following lines:

constructor(
     public afs: AngularFirestore,
     ....){}

The problem then is when I come to use super() in my derived class. I have to inject AngularFirestore into the derived class as well. That is, I have to have something like:

export class Variation extends Adjustment {
....
constructor(
    afs: AngularFirestore,
    .... ) {}
super (afs,
        ....)

The Variation class doesn't really need to know anything about AngularFirestore but I have to inject it in this class to enable it to be injected in the Adjustment class.

There must be a way to avoid this but I just can't figure it out.

Chris Curnow
  • 643
  • 5
  • 15

1 Answers1

0

Edit

I've replaced my previous answer with the following:

I did some more research on injectors and found this answer: https://stackoverflow.com/a/37482645/5348742.

We know Angular maintains an application-wide injector. We can access this injector by creating an property of type Injector at whatever module level we need. If we have registered the service in root we can get the injector in app.module.

In this way, we don't have to get the injector for the service in the constructor.

We get a reference to the service in app.module, export it and and then use it anywhere we need it.

Check the link above for further details on getting a reference to the service.

As far as using it elsewhere in the app it goes something like this.

In app.module

...

export let myService: MyService;

export class AppModule {

constructor(private router: Router,
        private injector: Injector){
        appInjector = this.injector;
        myService = appInjector.get(MyService)
  }
}

And then in the component or class where you want to use it:

import { myService } from 'app.module'

...

export class MyClass {

constructor(...){...}

  getSomething(){
    const something = myService.doSomething()
  }
}

In this way we can use a service without having to declare it in the constructor.

Chris Curnow
  • 643
  • 5
  • 15