1

In a simple angular app, I have created a test component like the one below:

test.component.ts

    import { Component } from '@angular/core';

    @Component({
      selector: 'test',
      template: `<h1>I am a test</h1>`,
      styles: [`h1 { font-family: Lato; }`]
    })
    export class TestComponent  {

    }

which I import in my app module like this:

app.component.ts

    import { Component } from '@angular/core';
    import { TestComponent } from './test.component';

    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent  {
      name = 'Angular';
      public TestComponent = TestComponent;
      dynamic = "Test";

      constructor(){
        console.log(TestComponent);
        console.log(this.TestComponent);
        console.log(this['TestComponent']);
        console.log(this[this.dynamic + 'Component']);
      }
    }

Getting help from this topic Angular 5 Dynamic variable name, I was able to get my component name dynamically (in the real example, the dynamic variable changes depending on an API call response).

My question is if there is any way to achieve the same result without having to pass the component as a local class variable, thus avoiding this line

public TestComponent = TestComponent;

without the this keyword the dynamic variable is not working, it gives me an error

console.log([this.dynamic + 'Component']);

I tried adding the code in a stackblitz but cannot seem to be able to share it (https://github.com/stackblitz/core/issues/215), but it is quite simple to copy the two files in a new empty stackbitz (https://stackblitz.com/edit/angular-f4ars5) to replicate.

Thanks in advance.

1 Answer 1

2

First you need to understand the following line

this['TestComponent']

In javascript you can access class properties in two ways. Class.property or Class["property"]. So when you are writing this["TestProperty"] you are effectively saying, Get AppComponentInstance.TestProperty

So console.log([this.dynamic + 'Component']); is like writing .TextComponent with nothing on the left side.

Now based on this, what are you trying to achieve exactly? Get the type or an instance of the type? What do you want to use the type for?

What you could do though would be to declare somewhere another global class and have these properties in them. Check this one for global variable declaration.

Your json could be something like this:

export class ComponentMapping
{
    private TestComponent = TestComponent;
}

And then in your class access the test component accordingly.

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

5 Comments

Thanks for explaining the first part. My goal is to dynamically add the desired component, which differs depending on the response of an API call. I have two components, lets call them "Component1" and "Component2", so my API call returns type = 1 and then I want to use that type to lets say dynamically get the name of the component "Component" + type . So it is my feeling the global variable solution with const is not applicable.
To do this, try the official way angular.io/guide/dynamic-component-loader with directive and component factory. Let me know if this works for you. This solution has an array of declared component types which is chosen based on a value, in your case backend.
That is exactly what I was following, then gut stuck with the parameter, I will give it another try and let you know if it worked out. Thanks again.
I finally used a new service (like the example) which returns an object that has key - value pairs, with keys representing the type (1, 2..) returned from my API. Thanks again for your comments, the guided me to the right direction. :)
Cheers! Glad I could help!

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.