0

Consider that I have 2 modules called A and B.

Let's say I have this class. It doesn't really "belong" to any module since it's a plain old Typescript class rather than an Injectable.

class Greeter {
  constructor(private greeting: string) {}

  greet(name: string) {
    console.log(`${greeting}, ${name}!`);
  }
}

Cool. Then, let's say module A exports a component that injects a Greeter instance.

@Component({ ... })
class GreetingComponent {
  name: string;

  constructor(private greeter: Greeter) {}

  greet() { this.greeter.greet() }
}

Nice. Now let's say module B has a service that extends the Greeter class. Module B imports module A.

@Injectable({
  providedIn: 'root'
})
class GentleGreeterService extends Greeter {
  constructor() {
    super('Hello');
  }

  greet(name: string) {
    super.greet(name);
    console.log('How are you doing?');
  }
}

Cool. Now, whenever I use GreetingComponent in module B, I expect a GentleGreeterService instance to be injected. However, I get no instance at all, but rather NullInjectorError: No provider for Greeter. How can I fix this?

Allan Juan
  • 2,048
  • 1
  • 18
  • 42

1 Answers1

1

You should read about providers in the official docs - I'm sure they'll explain it better than me.

Long story short - you only have a provider for GentleGreeterService but not for Greeter. You can add a provider (i.e. on module level, but also on component level) that will provide a Greeter but using some other class (or resolve it in other way, e.g. using a factory):

providers: [{provide: Greeter, useClass: GentleGreeterService}]
TotallyNewb
  • 3,884
  • 1
  • 11
  • 16
  • I see. The thing is I'm providing the service in one module and injecting it in another. I mean: module A needs to inject the service in `GreetingComponent`. Module B then provides a `Greeter` instance (using the snippet you provided) and imports Module A. I expected the instance provided by module B to be injected in module A's component, but I get a NullInjectorError instead. – Allan Juan Mar 10 '21 at 16:20
  • I think I could use a factory that returns the right service based on the route's URL but that would be wacky. https://stackoverflow.com/questions/59776198/angular-injecting-different-service-implementation-to-a-child-module – Allan Juan Mar 10 '21 at 16:27
  • I didn't fully read your modules setup, but the same solution still applies - I've quickly put up a stackblitz - hope it refelcts your issue: https://stackblitz.com/edit/angular-xvtjps – TotallyNewb Mar 10 '21 at 17:20
  • Thank you my friend, this works like a charm. You aren't *that* newb after all. – Allan Juan Mar 10 '21 at 17:35