6

I have an LWC component, let's say dummyComponent. Is there a way that i can get the name of this component from inside this component? Some like this:

this.getName();

The purpose behind this is that I'd like to make a custom metadata so administrators can set thresholds related to that component. The name of the metadata record would be the same as the name of the component. The component gets the threshold and analyses it against data from an api call. This component is in a flow and based on these thresholds(good or bad) one of the radio button choices will be set as default. The component in the flow is inserted dynamically so there can possible be any number of components available for insert. I hope this rambling summary helps to clarify why id like to know how to get the name.

4
  • 2
    Is this just a curiosity, or are you trying to solve a specific problem? This feels like it may be an X-Y Problem. Some background on why you need this would be useful.
    – sfdcfox
    Nov 12, 2020 at 13:31
  • @sfdcfox I have updated the question. thanks for the feedback.
    – Dane
    Nov 12, 2020 at 14:14
  • I still think that an @api one liner method added to each component would be better - you are still going to have to extend a class or import a module to get this regex based method into each of your component classes. But that's just IMO. Nov 13, 2020 at 18:08
  • Having said that, the supplied answer is a nice one. Nov 13, 2020 at 18:08

3 Answers 3

8

Either you can directly get info from this.template.host:

// testComponent.js
connectedCallback() {
  console.log(
    this.template.host.localName // c-test-component
      .split('-')              // ['c', 'test', 'component'] 
      .slice(1)                // removes ns prefix => ['test', 'component']
      .reduce((a, b) => a + b.charAt(0).toUpperCase() + b.slice(1)) // converts to camelCase => testComponent 
  );
}

Element.localName read-only property returns the local part of the qualified name of an element.

Having the local name of the component (e.g. c-test-component) we can process it to get get rid of the namespace prefix and to convert the dash-separated string to camelCase.

2
  • Oh, this is a great solution. Thanks a lot.
    – Dane
    Nov 19, 2020 at 10:23
  • Is this still working? I'm trying to get host details, but this.template.host is null
    – Nick C
    Jan 19, 2023 at 1:21
3

I riffed off this StackOverflow answer and came up with a one-liner that returns the name of the LWC component when deployed to Salesforce. It leverages the fact that JavaScript Error instances include the name of the file they came from in their stack property, so you just need the right regular expression to tease out the part you want:

/([^(/]*?)\.js/g.exec(new Error().stack)[1]

Something like this in a LWC called lwcApp will output "lwcApp" to the console:

import { LightningElement } from "lwc";

export default class LwcApp extends LightningElement {
  connectedCallback() {
    console.log(/([^(/]*?)\.js/g.exec(new Error().stack)[1]);
  }
}

To unpack this:

  • When you create a new Error instance, it comes with a stack property that looks like this (note the location of "lwcApp"):
Error
    at o.connectedCallback (modules/mynamespace/lwcApp.js:4)
    at callHook (aura_prod.js:37)
    at aura_prod.js:12
    at di (aura_prod.js:12)
    at Mo (aura_prod.js:12)
    ...etc...
  • The regular expression /([^(/]*?)\.js/g looks for text in between a forward slash or open parenthesis and the sequence ".js".
  • The exec function returns only the first match (conveniently for our purposes here). See MDN docs.
  • exec's return value is an array where the first item is the entire match and subsequent items are the parenthetical capture groups within the match. We care about the first capture group, hence [1].

Hope it helps!

4
  • Hello Matthew. Thanks for taking the time and making such a thorough answer.
    – Dane
    Nov 13, 2020 at 9:44
  • Thanks! Just realized there was a disconnect in my original answer. It supported a stack file reference like (modules/mynamespace/lwcApp.js:4) but not one like (lwcApp.js:4), should that kind of thing ever occur. Added support for the open parenthesis as a delimiter in addition to the forward slash. Nov 13, 2020 at 17:46
  • 2
    There's a MAJOR caveat of this approach: the stack trace in errors is not an API. It may change at any time. Aka this logic will break unannounced. Programmatic access to the rendered tag name is a good feature request. I recommend filing an issue at github.com/salesforce/lwc/issues. If you have a view on namespace vs not it'd be valuable to state that in the git issue. Nov 17, 2020 at 18:24
  • You're right, Kevin. I wasn't aware of Oleh's solution at the time I posted this. I would use his approach if I was implementing this today. Nov 18, 2020 at 16:14
1

This works well for me...

this.constructor.name[0].toLowerCase() + this.constructor.name.slice(1)

2
  • 1
    why not just this.constructor.name ???
    – Patlatus
    Oct 19, 2022 at 12:12
  • Don't use this approach, it is no longer working with LWS.
    – geoffswift
    Feb 14, 2023 at 10:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .