I have a doubt in LWC.

Can we declare a dynamic id inside template for:each

For the dynamic value, I used the data-set, and using the onclick event got the data-set value. Since I have multiple HTML elements, is there a way to add text.

Something Like this {rec.id+'-bttn'}

the requirement is I have multiple buttons that are displayed based on the records. I need to open the records by clicking the button lightning icon. Once the record is opened I need to change the icon of the button. For that, I need dynamic Id which should like {rec.id+'-bttn'} and {rec.id+'-attachment'}

2 Answers 2


You don't set the actual id of an element. These are mutated at runtime to be globally unique, and are managed by the runtime. Instead, just modify the data so that you have an icon name:

this.data = [...data].map(datum => ({ ...datum, iconName: '...' }));

Then, when you want to change the icon:

this.data.find(row => row.Id === event.target.dataset.recordId).iconName = '...';

I wrote a playground to demonstrate this.

import { LightningElement, track, api } from 'lwc';

export default class App extends LightningElement {
    @track data;
    connectedCallback() {
        // Just to show some data here //
        this.data = 'abcde'.split('').map(value=>({id:value,iconName:'utility:arrowup'}));
    toggle(event) {
        const row = this.data.find(row => event.target.dataset.rowId === row.id);
        row.iconName = row.iconName === 'utility:arrowup'? 'utility:arrowdown': 'utility:arrowup';

    <template for:each={data} for:item="row">
        <div key={row.id}>
            <lightning-button-icon onclick={toggle} data-row-id={row.id} icon-name={row.iconName}>

It is not possible to use the expressions in HTML but you have to generate the id in JS Controller itself. You can set the attribute like this. Also, you should not use the Id attribute as a query selector(Ids manipulated by the framework). Either use class or data attribute

In your controller just do this.

This how you can generate the properties in JS

let records = [...data];
records.forEach(element => {
    element.property1 = element.Id + '-bttn';
    element.property2 = element.Id + '-attachment';
this.records = records;

This is how you use them in HTML

<template for:each={records} for:item="item">
    <li key={item.Id}>
        {item.property1}, {item.property2}

You must log in to answer this question.

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