I am somewhat new to Angular 2 and its dependency injection abilities but have not quite been able to find an easy way to change a component dependency based on a route.
I.E. Given a component that takes a service.
MyReusableComponent {
constructor(private service: ServiceIWantToChange){}
}
Given I am adding a new route in a different part of the web application that will re-use the component.
I want to do something like this: NewAreaRoutingModule
{
path: "newRoute",
component: MyReusableComponent,
** my made up provider area ** -providers: [{provide:
ServiceIWantToChange, useClass: MyServiceWithChanges}]
}
This is what my mind ran to as a way to handle the location sensitive dependencies.
I thought I could provide an overriden implementation of the Component the provides a new depenency to the reusable component but I was hoping to just change the dependency in the route.
I've been doing research around resolvers etc but those seem to be more for providing data. I also noticed someone who injected the injector and did a if check to get the right in the component. Seen a couple of different ways. I am sure there is something I am missing about routing and DI but I coulnd't find anything simple. I know there are work arounds but was hoping to find a more elegant solution and just to know if what I want to do is even possible.
Thanks!
Here are the use case details in case I am approaching this wrong in general... In one area of a system I want to use a service that hits one version of rest endpoints on the server and in another part of the system I want to re-use the exact same component but have it send its requests to a different set of end points.
Combining injection tokens with route data gives you the desired result. Provide your services using different injection tokens:
const FIRST_SERVICE_TOKEN = new InjectionToken<string>("FirstService");
const SECOND_SERVICE_TOKEN = new InjectionToken<string>("SecondService");
@NgModule({
providers: [
{
provide: FIRST_SERVICE_TOKEN,
useClass: FirstService
},
{
provide: SECOND_SERVICE_TOKEN,
useClass: SecondService
}
],
})
class AppModule {}
then, specify dependency of each route using route data:
{path: 'first-route', component: MyComponent, data: {requiredService: FIRST_SERVICE_TOKEN}},
{path: 'second-route', component: MyComponent, data: {requiredService: SECOND_SERVICE_TOKEN}}
and finally use the route data to get the corresponding service
export class MyComponent{
private myService;
constructor(route: ActivatedRoute, injector:Injector){
const serviceToken = route.snapshot.data['requiredService'];
this.myService = injector.get(serviceToken)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With