1

I am trying to dynamically create components based on a string, and the dynamic components will have @Input fields that are needed from the parent. Here is a snippet of how I am dynamically creating the components

 import { Component1 } from '../../Component1.component';

@Component({
...
})
export class DynamicContainerComponent implements OnInit {
  static map = {
    'COMP1': Component1,
    ... // more components
  }
  @Input() dynamicComponentName;
  @Input() data1;
  @Input() data2;
  @Input() data3;
  constructor(    
    private vcRef: ViewContainerRef, 
    private resolver: ComponentFactoryResolver) { }

  ngOnInit(): void {
    const componentFactory = this.resolver.resolveComponentFactory(DynamicContainerComponent.map[this.dynamicComponentName]);
    const dynamicComponent = this.vcRef.createComponent(paymentGatewayFactory);
    dynamicComponent.instance.data1 = this.data1; // errors on this line and below
    dynamicComponent.instance.data2 = this.data2;
    dynamicComponent.instance.data3 = this.data3;

  }

}

However, on the lines annotated with comments saying there is an error, I am receiving

'Property data1 does not exist on type 'unknown''

Issue: All of the dynamic components will adhere to having these properties, however at the time of compilation the component loader will not know that the component contains the property,

If I were to supply the name of the component directly into the resolveComponentFactory as opposed to 'this.dynamicComponentName', then the error will not be there. But this obviously is what I'm trying to avoid as the dynamic component name will always be different.

Could anyone point me to any way to resolve having the type not be known at compile time? Or if I am dynamically creating the components in a wrong way.

Thank you in advance.

1
  • Hello, you can use prop method but it's not type safe. Can you instead try to specify the type of component on input decorators? Commented Jun 16, 2021 at 6:26

1 Answer 1

1

You could probably use the ['prop'] notation instead of the dot notation to access the input properties so typescript doesn't complain.

ngOnInit(): void {
    const componentFactory = this.resolver.resolveComponentFactory(DynamicContainerComponent.map[this.dynamicComponentName]);
    const dynamicComponent = this.vcRef.createComponent(paymentGatewayFactory);

    // new
    dynamicComponent.instance['data1'] = this.data1;
    dynamicComponent.instance['data2'] = this.data2;
    dynamicComponent.instance['data3'] = this.data3;

    // you might need to trigger this too to make sure it runs change detection so the UI of the dynamic component gets updated
    dynamicComponent.changeDetectorRef.detectChanges();
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.