0

I have created a LWC that displays EmailMessages at the Account level and allows users to search/filter these messages.

Apex Class:

public with sharing class ActivityListController {

//Get all Email Messages associated to an Account
@AuraEnabled (cacheable=true)
public static List<EmailMessage> getEmailMessages(List<Id> accountIds){

    List<Account> householdList = [SELECT Id, Prim_HH_Mem_Acct_Id__c, Sec_HH_Mem_Acct_Id__c FROM Account WHERE Id in :accountIds];
    List<Id> memberIds = new List<Id>();

    for(Account a : householdList){
        memberIds.add(a.Prim_HH_Mem_Acct_Id__c);
        memberIds.add(a.Sec_HH_Mem_Acct_Id__c);
    }

    List<EmailMessage> emList = [SELECT Id, Subject, RelatedToId, MessageDate, FromAddress, ToAddress, TextBody FROM EmailMessage WHERE RelatedToId in :memberIds ORDER BY MessageDate DESC];

    return emList;
}

LWC JS:

import { LightningElement, wire, api } from 'lwc';
import getEmailMessages from '@salesforce/apex/ActivityListController.getEmailMessages';
import { NavigationMixin } from 'lightning/navigation';

const actions = [
{ label: 'View', name: 'view' },
{ label: 'Edit', name: 'edit' },
];

const columns = [   
{ label: 'Subject', fieldName: 'EmailSubject', type: 'url', wrapText: true,
typeAttributes: { label: { fieldName: 'Subject' }, target: '_blank'} },
{ label: 'Message Date', fieldName: 'MessageDate', type: 'date',
typeAttributes:{day:'numeric',month:'short',year:'numeric',
hour:'2-digit',minute:'2-digit',second:'2-digit',hour12:true} },
{ label: 'From', fieldName: 'FromAddress', wrapText: true},
{ label: 'To', fieldName: 'ToAddress', wrapText: true},
//{
    //type: 'action',
    //typeAttributes: { rowActions: actions },
//},
];

export default class EmailMessageListLWC extends NavigationMixin(LightningElement) {

@api recordId;
availableEmails;
error;
columns = columns;
searchString;
initialRecords;

@wire(getEmailMessages, {accountIds: "$recordId"})  
wiredAccount({error, data}) {

    if (data) {
        this.availableEmails = data.map((record) => ({
            ...record,
            EmailSubject: '/' + record.Id
        }));
        
        this.initialRecords = this.availableEmails;
        this.error = undefined;
    } else if (error) {
        this.error = error;
        this.availableEmails = undefined;
    }
}

handleRowAction( event ) {
    const actionName = event.detail.action.name;
    const row = event.detail.row;
    switch ( actionName ) {
        case 'view':
            this[NavigationMixin.Navigate]({
                type: 'standard__recordPage',
                attributes: {
                    recordId: row.Id,
                    actionName: 'view'
                }
            });
            break;
        case 'edit':
            this[NavigationMixin.Navigate]({
                type: 'standard__recordPage',
                attributes: {
                    recordId: row.Id,
                    objectApiName: 'Account',
                    actionName: 'edit'
                }
            });
            break;
        default:
    }
}

handleSearchChange(event) {
    this.searchString = event.detail.value;
}

handleSearch(event) {
    const searchKey = event.target.value.toLowerCase();

    if (searchKey) {
        this.availableEmails = this.initialRecords.filter((rec) => {
            const valuesArray = Object.values(rec);
            return valuesArray.some((val) => 
                String(val).toLocaleLowerCase().includes(searchKey)
                );
        });

    } else {
        this.availableEmails = this.initialRecords;
    }        
}
}

When I deploy this to my full copy sandbox and add it to the record page, when I try to load an Account record, Chrome freezes before finally displaying a "Not enough memory to open this page" screen. When I hover over the Salesforce tab in Chrome, it shows "High Memory Usage: 1.5 GB" (normally, this is ~200 MB in production).

Can anyone let me know which part of my code is causing so much memory usage? Thanks.

1
  • You probably have your answer, but remember that you can monitor a lot of information in Chrome by opening the Inspector. You can view the data being returned through wires or imperative Apex calls and even debug the LWC's JavaScript.
    – Phil W
    Commented Jan 22 at 16:59

1 Answer 1

0

I don't see you using TextBody in the lwc even though you have queried in apex method

List<EmailMessage> emList = [SELECT Id, Subject, RelatedToId, MessageDate, FromAddress, ToAddress, TextBody FROM EmailMessage WHERE RelatedToId in :memberIds ORDER BY MessageDate DESC];

removing this from query would reduce the size of result coming to LWC. TextBody will have stored the email content which is greater in size.

Updated Answer

Another way you can handle this instead of returning all the email result in one call and searching it in client side, you can make apex call each time users search for it. This way you won't hit the limit.

2
  • Yes, I did consider this, but there was a business requirement that the search results return records where the searchKey is in the body of the email as well. If I need to remove TextBody from the query to improve performance, then I'll do that, but I was trying to accommodate the ask from leadership in the initial build
    – tonydigi1
    Commented Jan 22 at 17:07
  • @tonydigi1 check my updated answer. Commented Jan 22 at 17:31

You must log in to answer this question.

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