2

I need to load several components in a dynamic way. That is why I have created a parent component to do the job (depending on the value of this.rink), like:

ngAfterViewInit() {
    switch (this.rink) {
        case 'ITCO':
            this.templateFreetext = FreetextITCOComponent;
            break;

        case 'INH':
            this.templateFreetext = FreetextINHComponent;
            break;

        default:
            this.templateFreetext = FreetextBERComponent;
            break;
    }

    const cfr = AppInjector.get(ComponentFactoryResolver);
    const factory = cfr.resolveComponentFactory(this.templateFreetext);
    this.componentRef = container.createComponent(factory);
    
    this.componentRef.instance.data = data;
    this.componentRef.changeDetectorRef.detectChanges();
}

This works well, but for what reason ever I'm not able to use any pipes inside the HTML template of templateFreetext.

    ...
    <div class="text-right text-warning">
        {{ data.day | date:'EEEE, dd.MM.yyyy' }}
    </div>
    ...

This returns Error: The pipe 'date' could not be found!

My question is now how I can use dynamic created components and pipes? What did I forget?

Usama Abdulrehman
  • 1,041
  • 3
  • 11
  • 21
Lars
  • 920
  • 1
  • 14
  • 34
  • Which version of Angular do you use? I had this problem when migrating to NG9 with Ivy. Before NG9 you had to add dynamic components to the "entryComponents" in the module. Maybe that will fix it? – T. van den Berg Jul 09 '20 at 10:51
  • @T.vandenBerg im using NG10. So I don't have "entryComponents" anymore – Lars Jul 09 '20 at 10:54
  • I created a Blitzstack to test it. First you should avoid changing views in lifecycle hooks. A hack is to set a time out to 0 so it will only applied after the loading is done. https://angular-8vztax.stackblitz.io I do have to define the entryComponent though. Maybe because I use the DI. – T. van den Berg Jul 09 '20 at 11:31
  • same problem ; have you find the solution ? – firasKoubaa Feb 15 '22 at 10:01

2 Answers2

0

you may declare your dynamic components as declarations of a specific separated module , without exporting them in it (you may call it dynamicElementsModule) , and then import this module in the appModule

Like that you can use any toool in the commonModule (such as pipes)

@NgModule({
  imports: [CommonModule],
  declarations: [
    // You may here import you dynamic components
    FirstDynamicComponent,
  ],
})
export class DynamicElementssModule {}

app.module.ts

import { DynamicElementssModule } from './dynamic-elements/dynamic-elements.module';

    @NgModule({
      imports: [CommonModule, BrowserModule, FormsModule, DynamicElementssModule],
      declarations: [AppComponent],
      bootstrap: [AppComponent],
    })
    export class AppModule {}

Finally you can use the pipes :

dynamic.component.ts

export class FirstDynamicComponent implements OnInit {
  @Input() customDataInputs: any;
  constructor() {}

  ngOnInit() {}
}

dynamic.component.html

{{ customDataInputs | json }}

Here is a full working snippet

https://stackblitz.com/edit/angular-ivy-nvjzga?file=src/app/dynamic-elements/first-dynamic-comp/first-dynamic.component.html

firasKoubaa
  • 6,439
  • 25
  • 79
  • 148
0

It seems that Pipes are not working right now using this method, as we can see here (on universal, but i have the same behavior on another project): https://github.com/angular/universal/issues/1878

You can use the declarations to bypass the problem for the moment

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 16 '22 at 12:42