Reputation: 376
I'm trying to encapsulate my element ids by adding the instance id like this:
<label for="id-{{ unique }}-name"></label>
<input id="id-{{ unique }}-name" type="text" formControlName="name">
I previously worked with this: https://stackoverflow.com/a/40140762/12858538. But after upgrading Angular from 7 to 9 this seems deprecated. I was thinking about a simple helper service, which would generate unique ids for my app.
Something like this:
@Injectable()
export class UniqueIdService {
private counter = 0
constructor() {}
public getUniqueId (prefix: string) {
const id = ++this.counter
return prefix + id
}
}
inspired by lodash uniqueid
But I did rather use angulars build in ids.
So my currently solution is to extract the id from the components _nghost
attribute.
constructor ( private element: ElementRef, ) {
const ngHost =
Object.values(this.element.nativeElement.attributes as NamedNodeMap)
.find(attr => attr.name.startsWith('_nghost'))
.name
this.unique = ngHost.substr(ngHost.lastIndexOf('-') + 1)
}
But I'm not perfectly happy with this solution and I'm looking for a direct access to the id.
Does anyone know how to access this?
Upvotes: 14
Views: 15045
Reputation: 41
You can use crypto.randomUUID()
which is provided by Crypto API in browsers. Support is great.
https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID
https://caniuse.com/mdn-api_crypto_randomuuid
Upvotes: 4
Reputation: 671
Neither _nghost
nor ɵcmp
are unique across component instances. They should not be used for that purpose.
Your UniqueIdService
is the easiest and the safest solution. (The counter
property could be static to be sure that every instance of the service returns unique ID).
Upvotes: 1
Reputation: 214047
The unique ID in Angular 9 can be represented as:
_nghost - par - 2
| | |
static APP_ID componentDef.id
In order to access componentDef.id
you can do the following:
export class SomeComponent implements OnInit {
unique = this.constructor['ɵcmp'].id;
where ɵcmp
is a private variable NG_COMP_DEF
Upvotes: 10