6

So I've been facing this weird issue but I'm not sure if it's a bug or it's me missing something here.
So I have a component called TestComponent and in the AppComponent I have a button when I click on it I get the name of the TestComponent by doing this TestComponent.name.

AppComponent:

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

@Component({
  selector: 'app-root',
  template: '<button (click)="showName()">Show</button>'
})
export class AppComponent {    
  showName(){
    console.log('component name: "' + TestComponent.name + '"');
  }
}

As you can see by clicking on the button I want to get the TestComponent's name which basically "TestComponent"
The problem is that this works well on development mode and if I call ng build too works fine and this is what I get in the console:

enter image description here

And when I call ng build --prod, to compress files and reduce their size, I get this result:

enter image description here

Is this normal ?!

Community
  • 1
  • 1
SlimenTN
  • 3,383
  • 7
  • 31
  • 78
  • how is the value assigned to the variable `name` ? – Aravind Oct 04 '17 at 09:14
  • @Aravind no it's not a variable in TestComponent class, it's a function on TypeScript that gives you the name of the component as a string like in Java `class.getClassName()` – SlimenTN Oct 04 '17 at 09:16

4 Answers4

6

Function name contains actual function name. If the function is minified to one-letter name, it loses its original name. It should never be relied on in applications that can possibly be minified at some point i.e. every client-side application. There may be exceptions for Node.js.

name is read-only in some browsers and and thus can't be overwritten. If a class needs identifier, it should be specified explicitly under different name:

class Foo {
  static id = 'Foo';
  ...
}

Here is a related question.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
3

Yes, this is normal since angular-cli/webpack and other tools are changing the class name by minifying the JavaScript code. So after minification in production build, you'll always only see one letter or something similar.

Don't use this name in your logic because it will break in production.

Moema
  • 863
  • 4
  • 10
  • so what's is the solution ? I actually faced this problem when I was working on an application that is based on many dynamic components and I need to get the name of a specific component after a specific event !! – SlimenTN Oct 04 '17 at 09:20
  • create your own identifier – Moema Oct 04 '17 at 09:21
0

I just answered a related question here

To workaround mangling class names, you can create a function and check if it is equal to the class you want to test. In this case for TestComponent, you could use this:

getType(o: any): string {
      if (o === TestComponent)
          return 'TestComponent';
}

And calling it will print the Component name:

console.log(getType(TestComponent)); // will print 'TestComponent'
Asheq Reza
  • 87
  • 1
  • 7
  • I feel like this is an ugly ugly way to do it... but... it was by far the simplest way to get past the roadblock I faced. Thanks! – Sean Halls Apr 12 '20 at 04:20
0

The best way I found was to use a library that renames the class at compile time, works similar to the C # nameof. nameof<MyInterface>(); Result: "MyInterface"

https://github.com/dsherret/ts-nameof

Erli
  • 1