Smokey Dawson
Smokey Dawson

Reputation: 9230

Dynamically adding components Angular 5

I've got a problem and I'm not sure what the issue is.

So I want to dynamically add components to another component I have using query params.

So I have the component dynamically being added but it doesn't work when I do it using a query string with the exact same name

so the route is set up like this

{
    path: 'tool-view/:tool',
    component: ToolViewerComponent
}

then In app.module I'm adding the component I'm trying to add dynamically to the entryComponents like so...

entryComponents: [
    CoolToolComponent
]

then In my toolViewerComponent I have this

import { Component, OnInit, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

// Tool Components
import { CoolToolComponent } from '../tools/cool-tool/cool-tool.component';

@Component({
  selector: 'app-tool-viewer',
  templateUrl: './tool-viewer.component.html',
  styleUrls: ['./tool-viewer.component.scss']
})
export class ToolViewerComponent implements OnInit {

  @ViewChild('entry', { read: ViewContainerRef }) entry: ViewContainerRef;

  constructor(
    private _resolver: ComponentFactoryResolver,
    public activatedRoute: ActivatedRoute
  ) { }

  ngOnInit() {
    // Resolvers
    const coolFactory = this._resolver.resolveComponentFactory(CoolToolComponent);
    const toolComponent = this.entry.createComponent(coolFactory);
  }
}

okay so this works, the component is added onto the page no problem now when I try to do this...

@ViewChild('entry', { read: ViewContainerRef }) entry: ViewContainerRef;

constructor(
  private _resolver: ComponentFactoryResolver,
  public activatedRoute: ActivatedRoute
) { }

ngOnInit() {
  this.activatedRoute.params.subscribe(params => {
    this.createComponent(params.tool);
  });
}

createComponent(tool) {
  const toolFactory = this._resolver.resolveComponentFactory(tool);
  const toolComponent = this.entry.createComponent(toolFactory);
}

but this doesnt work and I get the error

No component factory found for CoolToolComponent. Did you add it to @NgModule.entryComponents?

I'm not entirely sure whats going on here, but I think I might be the fact that in the createComponent(tool) the tool comes in as a string "CoolToolComponent" and not as the CoolToolComponent ??

But I'm not sure.

The only other way I can think of doing this is to use a bunch of if Statements.

if(params.tool = 'CoolToolComponent') {
    const hba1cFactory = this._resolver.resolveComponentFactory(Hba1cTracker);
    const toolComponent = this.entry.createComponent(hba1cFactory);
} etc..

and I would like to avoid doing that.

Any help would be appreciated!

Thanks

Upvotes: 2

Views: 1480

Answers (1)

sugarme
sugarme

Reputation: 761

You can create an array holding your dynamic component set with routing params are key of corresponding components. Something like this:

import { Component } from '@angular/core';
...
import { ToolComponent} from './tool.component';

@Component({...})
export class ToolViewerComponent  {
  ...

  tools: Component[] = new Array();

  constructor() {
    // add more tools here...
    this.tools['tool'] = ToolComponent;
  }

  ngOnInit() {
  this.activatedRoute.params.subscribe(params => {
    let toolName = param.tool;
    this.createComponent(this.tools[toolName]);
  });
}

createComponent(tool: Component) {
  const toolFactory = this._resolver.resolveComponentFactory(tool);
  const toolComponent = this.entry.createComponent(toolFactory);
}

}

Upvotes: 1

Related Questions