[SalesForce] Dynamic Id declaration with added text (Id-Text) in LWC

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'}

Best Answer

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>
    <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}>
            </lightning-button-icon>
        </div>
    </template>
</template>