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.

Nitin Zadage
  • 524
  • 6
  • 21

1 Answers1

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.

Athanasios Kataras
  • 20,791
  • 3
  • 24
  • 45
  • 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. – Travel and code enthousiast Nov 22 '19 at 08:41
  • 1
    To do this, try the official way https://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. – Athanasios Kataras Nov 22 '19 at 08:56
  • 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. – Travel and code enthousiast Nov 22 '19 at 10:23
  • 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. :) – Travel and code enthousiast Nov 26 '19 at 14:00
  • Cheers! Glad I could help! – Athanasios Kataras Nov 26 '19 at 14:54