Vishal Sakaria
Vishal Sakaria

Reputation: 1397

I want to display different components based on different endpoint data in Angular 2

I am working on a project where I need to display a different template/component based on what my endpoint response is.

For example

{data: {type: 1, textToDisplay: 'I want beans'} }

Should inject Component 1 into the main app template.

If the data is

{data: {type: 2, textToDisplay: 'I want cheese', numberToDisplay: '101' } }

Should inject Component 2 into the main app template and of course Component 2 would be different to Component 1 because there's extra properties.

I really don't want to use bad practice by appending elements into the main app template nor do I want to write a massive template with [if] directives as we could have many, 5-8, different components to render and it would bloat the template.

What's a suitable way?

Upvotes: 1

Views: 473

Answers (1)

eko
eko

Reputation: 40647

As @Günter mentioned, you can use DynamicComponentLoader

@Component({
  selector: 'my-app',
  template: `<button (click)="addCmp()" #theBody>add</button>
  `,
  directives: [BaseDynamicComponent]
})
export class AppComponent {
  @ViewChild('theBody', {read: ViewContainerRef}) theBody;
  cmp:ComponentRef;

  constructor(injector: Injector,private resolver: ComponentResolver) {}

  addCmp(data){
    console.log('adding');
    this.resolver.resolveComponent(BaseDynamicComponent).then((factory:ComponentFactory<any>) => {
      this.cmp = this.theBody.createComponent(factory);
      //and you can set your BaseDynamicComponent's 'extra' properties here
      this.cmp.instance.numberToDisplay = data.numberToDisplay;
    });
  }
  }

This will add the BaseDynamicComponent under the #theBody element.

Here's an example plunkr:

Plunker

If you click the add button it will add a new component with its test field assigned to "the test"

this.cmp.instance.test = "the test";

Or you can predefine the components like in @Günter's answer(https://stackoverflow.com/a/36325468/5706293) and then append them accordingly

Upvotes: 2

Related Questions