1

I'm trying to figure out how to get a reference to a class in Angular 2+ (Angular 5) from a string at runtime. I tried the examples on this page. This one didn't work for me:

console.log((<any>Object).create(window[className])); // undefined

And the others are using an import, which I'm trying to avoid.

I'm not using a namespace, but don't know if Angular has one of its own. I tried snooping on the window object to see if I could find anything. All I found were getAllAngularRootElements, getAllAngularTestabilities, and getAngularTestability, but those didn't seem like what I was looking for.

1
  • 1
    You can't do this without assigning it first. Please explain why you're trying to do this, what the actual problem you're trying to solve is. You shouldn't need to mess around with global variables, and even if you do have a valid use case, identifying a function by its name instead of by reference doesn't make a lot of sense. Commented Apr 5, 2018 at 0:18

1 Answer 1

3

I had a similar need once for dynamically rendering components and only having a string reference to the class that needed to be injected into the page (dynamic dashboard type of app). I ended up doing the following:

  • Create service to hold onto reference of component by string name
  • Inject service into module component was part of and register the component
  • Inject the service into the component that needed to get the component by string name

This was roughly what I had for the service (the class took care of actually creating the dynamic component instead of getting the reference like below):

export class DynamicComponentService {
    private dynamicComponentTypes: { [type: string]: Type<BaseInterfaceSectionComponent> } = {};

    registerDynamicComponentTypes(...dynamicComponentTypesToRegister: { component: Type<BaseInterfaceSectionComponent>, name: string }[]) {
        dynamicComponentTypesToRegister.forEach(dynamicComponentType => {
            this.dynamicComponentTypes[dynamicComponentType.name] = dynamicComponentType.component;
        });
    }

    getDynamicComponentType(name: string): Type<BaseInterfaceSectionComponent> {
        return this.dynamicComponentTypes[name];
    }
}

I was unaware until doing this, but you can actually inject dependencies into a module's constructor. I used this feature to use the service to register the dynamic components:

export class BarChartContentModule {
    constructor(dynamicComponentService: DynamicComponentService) {
        const dynamicComponent = { component: BarChartContentComponent, name: 'BarChartContentComponent' };
        dynamicComponentService.registerDynamicComponentTypes(dynamicComponent);
    }
}

Not sure if this is what you were looking for, but figured I'd share.

Sign up to request clarification or add additional context in comments.

3 Comments

That's a very nice solution!
@Daniel W Strimpel ,, very nice solution, may i ask what's BaseInterfaceSectionComponent?
@JosephKhella the BaseInterfaceSectionComponent was just a base class that the dynamic components inherited some base behaviors from (just some app specific logic that was consistent). It also served as the interface to work with all of the components in a generic way (i.e. same inputs/outputs).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.