Angular 5 - instantiate a component from its name as a string
Asked Answered
H

2

9

I know how to init components using ComponentFactoryResolver.resolveComponentFactory(AComponentType)

but the method expects a Type, while in my code I have the name of the type as a string.

In the Angular API is there a method to resolve by string? If not, how can I convert a string to a Type in TypeScript?

In case that none of the above is possible I will resort to a map but it's not so straightforward as the components I need to instantiate will come from remotely fetched UMD angular component library.

Hintz answered 8/3, 2018 at 8:7 Comment(3)
Possible duplicate of How to get a class from a string in TypeScript/JavaScript in an Angular 2 application?Whitewash
#40529092Skyeskyhigh
You should take a look to this: angular.io/guide/dynamic-component-loaderHydrolytic
E
5

You can do the following:

const classesMap = {
  AComponentType: AComponentType,
  BComponentType: BComponentType
}

And then:

CreateDynamicComponent(typeName: string) {
    ...
    const componentFactory = ComponentFactoryResolver.resolveComponentFactory(classesMap[typeName].prototype.constructor)
    ...
}
Exodontist answered 26/7, 2018 at 8:33 Comment(0)
H
2

I had the same problem, where i need to use a string to select what component to build. After some digging I created a list of the components that is added to the NgModuleexport and entryComponents lists.

template-components.ts

export const TEMPLATE_COMPONENTS: Type<any>[] = [
    Temp1Component,
    Temp2Component
  ]

in my NgModule class I just add TEMPLATE_COMPONENTS to both exports and entryComponents

In the component with the ComponentFactoryResolver you generate a list of Types, with the same string as a key.

let templateTypes: { [name: string]: Type<{}> } = 
    TEMPLATE_COMPONENTS.reduce((p, c) => { p[c.name] = c; return p }, {})

// templateTypes = {'Temp1Component':Temp1Component,...}

this.componentFactoryResolver.resolveComponentFactory(templateTypes[string]);

This means that you only have to add the components to one place, simplifying adding more components.

Its probably possible to skip the whole TEMPLATE_COMPONENTSin a separate list step and get the list directly from the NgModuleclass, but that will be sometime in the future.

Hasseman answered 8/3, 2019 at 14:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.