Populate and iterate through Object in LWC

javascriptlightning-web-components

Originally I tried building a Map and iterating through that to dynamically build a Lightning Accordion with corresponding Sections but I learned that I could not iterate over a Map.

I've tried to create an Object and iterate over that instead but I fear my approach in building the object is stuck in how I would try to do this from an Apex perspective rather than an optimal JS approach.

The optimal data structure for the Object would be something like this:

customObject = {name : perm.outputType, values : [perm]}

This is so all of the permission records of a certain type would be grouped together in an Array and I can loop through those and display them within the section.

Function Code:

  if (this.permissionsObject !== undefined && Object.hasOwn(this.permissionsObject, perm.outputType)) {
    console.log('entered step 1');
    let typeObject = Object.getOwnPropertyDescriptor(this.permissionsObject, perm.outputType);
    console.log(typeObject);
    let arrayValues = Object.values(typeObject);
    Object.defineProperty(this.permissionsObject, perm.outputType, { value: [...arrayValues, perm], configurable: true });
  } else {
    Object.defineProperty(this.permissionsObject, perm.outputType, { value: [perm], configurable: true });
  }

Relevant LWC Html:

<lightning-accordion allow-multiple-sections-open onsectiontoggle={handleSectionToggle}
        active-section-name={activeSections}>
        <template for:each={permissionsObject.key} for:item="perm">
          <lightning-accordion-section label="{perm}">
            <template for:each={perm.values} for:item="permValue">
              <div key={perm.outputUniqueId}>{permValue.outputName}</div>
            </template>
          </lightning-accordion-section>
        </template>
      </lightning-accordion>

Any assistance which could be provided on a more optimal way to approach this from a JS perspective would be great. Thanks!

Best Answer

You can convert a Map to a usable array with Object.entries:

let values = Object.entries(source).map(([key, value]) => ({ key, value }))

This is an efficient way to translate your map into something you can iterate over.

Of course, you lose control over the ordering of the keys, so you may want to sort by keys afterwards.

Related Topic