Dandy
Dandy

Reputation: 979

Angular dynamic module provider

I have a module which should have injected a service depending on the router path, e.g. for a path with /demo it should have injected a DemoService and for paths without /demo it should have provided a UserService.

How can I implement such functionality?

Of course I could inject both services and in the module itself determine whether it should use a DemoService or a UserService but then the module wouldn't be reusable in other apps.

Upvotes: 3

Views: 4568

Answers (1)

nakhodkin
nakhodkin

Reputation: 1465

  1. Define a type for a provider, let's say, in your case you can have a class provider, like a factory class, e.g.
abstract class DataService {
  abstract doSomething(): void;
}

class FactoryService {
  activeService = new BehaviorSubject<DataService>();

  getService(): Observable<DataService> {
    return this.activeService.asObservable();
  }
}

class DemoService extends DataService {
  doSomething(): void {
    console.log('DemoService');
  }
}
class UserService extends DataService {
  doSomething(): void {
    console.log('UserService');
  }
}

take the shared parts of an API of your services to an abstract class, so the consumers should rely on the interface.

  1. In your module which should provide either DemoService or UserService define your provider as a factory e.g.
providers: [{
  provide: FactoryService,
  useFactory: (route: ActivatedRoute) => {
    const factoryService = new FactoryService();
    const url = route['_routerState'].snapshot.url;

    url.startsWith('/demo/')
      ? factoryService.activeService.next(new DemoService())
      : factoryService.activeService.next(new UserService());

    return factoryService;
  }
  deps: [ActivatedRoute]
}],
  1. In your consumer component, you now can get access to the particular service through ServiceFactory which should provide a proper service
constructor(private factoryService: FactoryService) {
  this.factoryService.activeService.subscribe((activeService: DataService) => {
    // Here you can now do stuff with an proper service
  });
}

Hope, you've got the idea...

Upvotes: 4

Related Questions