Search code examples
angularangular-routingangular-pipeangular-providers

Provided Pipe doesn't have access to route resolved data


I have a pipe that needs to have access to route data in order to be well constructed :

export class LevelPercentagePipe implements PipeTransform {

  levelDictionnary: LevelDictionnary;

  constructor(private route: ActivatedRoute) {
    this.levelDictionnary = new LevelDictionnary(this.route.snapshot.data['prerequisiteLists']);
  }
}

This data is resolved in routing module :

{
  path: 'xxx',
  loadChildren: './xxx/xxx.module#XxxModule',
  resolve: {
    prerequisiteLists: PrerequisiteResolver
  }
}

It works in other places of my application if the pipe is used in the html template. But in this particular case I need to use this pipe in my component.ts file. So I provided it in the specific feature module :

@NgModule({
  declarations: [...],
  imports: [...],
  providers: [LevelFilterPipe],
})

But now when it's injected in my component constructor it seems not to know about the data in the ActivatedRoute.

constructor(
        private profileService: ProfileService,
        private nameFilterPipe: NameFilterPipe,
        private levelFilterPipe: LevelFilterPipe
      ) {}

This doesn't work.

So instead I need to construct the pipe manually.

constructor(
    private profileService: ProfileService,
    private route: ActivatedRoute,
    private scorePipe: ScorePipe,
    private nameFilterPipe: NameFilterPipe
  ) {
    // We have to inject route data and scorePipe manually because it's not injected automatically.
    this.levelFilterPipe = new LevelFilterPipe(this.route, this.scorePipe);
  }

Is there another way to inject the data from ActivatedRoute automatically?


Solution

  • You need to add your pipe to your component's providers list. Now your pipe injection will create a new instance of your pipe with the updated ActivatedRoute data.

    @Component({
      selector: '...',
      template: `...`:
      providers: [ YourPipeName ]
    })
    

    Here is a working StackBlitz project example of your question. Take a look at the file hello.component.ts, this component is routed with a param like you've mentioned, remove the provided pipe in this component to reproduce your problem.