I am trying to group records by category.

My Controller returns a list of records and the results are as follows:

List<AssetsIncome__c> = [SELECT FileTitle__c, FileLinkId__c, FileExtension__c, FileCategory__c from AssetsIncome__c];


What I want to display on the front end is a collapsable tree of category and all the files per category

> FileCategroy
  > FileTitle1
  > FileTitle2

> FileCategory2
  > FileTitle1
  > FileTitle2 

Per the sample above
> Income
  > File1.docx
  > File3.docx
> Asset
  > File2.docx

Can someone assist me with the JS and HTML needed to format my response as above please?

1 Answer 1


hope everything goes well,

Here it's a simple way to make your lwc, Please add more style or more complexity as you want, I am using the accordion component https://developer.salesforce.com/docs/component-library/bundle/lightning-accordion/example

in your html file.

    <lightning-accordion allow-multiple-sections-open="true">
        <!-- Loop through each File Category -->
        <template for:each={fileCategory} for:item="fileCategoryItem">
                <!-- Loop through file in the current file category -->
                <template for:each={fileCategoryItem.files} for:item="fileItem">
                    <div key={fileItem.Id}>
                        <!-- Add file properties here -->

in your js

import { LightningElement, wire } from 'lwc';
import getFiles from '@salesforce/apex/DummyController.getFiles';

export default class FilesAccordion extends LightningElement {
    // Holds a map of category file names to their associated files
    fileCategory = [];

    connectedCallback() {
        // init 

    callingGetFiles() {
        .then(result => {
            console.log('result ===> '+result);
            this.fileCategory = this.groupFilesByCategory(result);
        .catch(error => {
            // handle error
            this.fileCategory = undefined;

    // Helper function to group files by file category name
    groupFilesByCategory(files) {
        const fileCategoryMap = {};

        files.forEach(file => {
            const fileCategory = file.FileCategory__c;
            if (!fileCategoryMap[fileCategory]) {
                fileCategoryMap[fileCategory] = [];

        // NEW: Convert the map into an array of objects
        const fileCategories = Object.keys(fileCategoryMap).map(fileCategoryName => ({
            fileCategoryName: fileCategoryName,
            files: fileCategoryMap[fileCategoryName],
        console.log('fileCategories ===> '+JSON.stringify(fileCategories));
        return fileCategories;

Hope this helps you, Note: I didn't test this in an org, please use this as a guide.

  • Hi @vivi-ramji, thank you for the response. I am getting the error "Template Expression doesn't allow computed property" on the the following line: <template for:each{fileCategory[fileCategoryName]} for:item="fileItem">
    – degmo
    Sep 5, 2023 at 5:18
  • Oh, I noticed that we cannot use access map[key] in lwc, so you need to make a change to your html and js file, to use an array of arrays and render properly in your html.
    – vivi-ramji
    Sep 5, 2023 at 6:26
  • I edited the answer, please validate. Again, that is a guide component.
    – vivi-ramji
    Sep 5, 2023 at 6:40
  • That worked like a charm vivi-ramji. Thanks for the help and will go through the code in detail to understand how it works.
    – degmo
    Sep 5, 2023 at 14:55

You must log in to answer this question.

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