0

This is linked to my recent post Data Not Displaying When Converting Visualforce Page to LWC concerning the display of grouped records in a table using LWC in Salesforce. Issue has been resolved so far.

But I noticed that only values from Module and Name fields are displaying. Table does not display Phone and Email values even though I already included both from html and apex query. Tried checking debug logs and all four fields have values.

Meanwhile, here are the updated codes:

contactLWC.html

<template>

    <table class="slds-table slds-table_cell-buffer slds-table_bordered ">
     <thead>
      <tr class="slds-line-height_reset">
       <th class="" scope="col">
        <div class="slds-truncate" title="contactModule">Module</div>
       </th>
       <th class="" scope="col">
        <div class="slds-truncate" title="contactName">Name</div>
       </th>
       <th class="" scope="col">
        <div class="slds-truncate" title="contactEmail">Email</div>
       </th>
       <th class="" scope="col">
        <div class="slds-truncate" title="contactPhone">Phone</div>
       </th>
      </tr>
     </thead>
     <tbody>
      <template if:true={mapData}>
       <template for:each={mapData} for:item="keyValue">
        <tr key={keyValue.key} class="slds-hint-parent">
            <th scope="col">
                <div>{keyValue.key}</div>
            </th>
            <template for:each={keyValue.value} for:item="value">
                <div key={value.Name}>
                    {value.Name}
                </div> 
                <div key={value.Email}>
                    {value.Email}
                </div> 
                <div key={value.Phone}>
                    {value.Phone}
                </div> 
            </template>
        </tr>      
       </template>
      </template>
     </tbody>
    </table>
</template>

contactLWC.js

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

import getDataFromApex from '@salesforce/apex/ContactController.getData';

export default class contactLWC extends LightningElement {

    @track mapData = [];

    @wire(getDataFromApex) 
    wiredcontactdata({ data, error }) {
        if (data) {
            for(let key in data) {

                if (data.hasOwnProperty(key)) { 
                    this.mapData.push({key: key, value: data[key]});
                }
            }
        } else if (error) {
            window.console.log(error);
        }
    }

}

ContactController.cls

public class ContactController{

    @AuraEnabled(cacheable=true)

    public static Map<String, List<ContactWrapper>> getData()
    {

     Map<String, List<ContactWrapper>> mapModule = new Map<String, List<ContactWrapper>>();
     Map<String, Integer> moduleCountMap = new Map<String, Integer>();

     List<Contact> contactList = [SELECT Name, Email, Phone, Module__c 
            FROM Contact 
            WHERE Module__c != null 
            ORDER BY Module__c];

     for(Contact contObj:contactList)
     {
      List<ContactWrapper> conWrapperList = new List<ContactWrapper>();

      if(mapModule.containsKey(contObj.Module__c))
      {

       conWrapperList = mapModule.get(contObj.Module__c);


       conWrapperList.add(new ContactWrapper(contObj));

       mapModule.put(contObj.Module__c, conWrapperList);


       moduleCountMap.put(contObj.Module__c, conWrapperList.size());
      }
      else
      {

       conWrapperList.add(new ContactWrapper(contObj));
       mapModule.put(contObj.Module__c, conWrapperList);


       moduleCountMap.put(contObj.Module__c, conWrapperList.size());
      }
     }

     return mapProjectType;

    }

    public Class ContactWrapper {

     public ContactWrapper(Contact contObj)
     {
      this.Name = contObj.Name;
      this.Email = contObj.Email;
      this.Phone = contObj.Phone;
      this.Module = contObj.Module__c;
     }

     @AuraEnabled
     public String Name {get;set;}
     @AuraEnabled
     public String Email {get;set;}
     @AuraEnabled
     public String Phone {get;set;}
     @AuraEnabled
     public String Module {get;set;}
    }


   }

Been looking for other tutorials on the Web for ideas, but Email and Phone values still not displaying. This is kind of frustrating. Hoping someone could help me on this.

4
  • Any particular reason you rolled your own html rather than using lightning-datatable?
    – Adrian Larson
    Commented Jun 8, 2020 at 15:03
  • I've tried using it at first, but I am having difficulty with using lightning-datatable, especially when I am trying to obtain grouping. I have to merge duplicate cells. It worked with html, so I sticked with it.
    – Ertyq
    Commented Jun 8, 2020 at 15:08
  • Might seem crazy and Im not sure itll work but try changing value to record. Sometimes using super generic variables causes unknown conflicts. Another thing to do is to check your developer console in your browser to see if there are any JS errors.
    – gNerb
    Commented Jun 8, 2020 at 15:17
  • @gNerb tried this also, but it still same result. There are no JS errors as well.
    – Ertyq
    Commented Jun 9, 2020 at 9:08

3 Answers 3

0

Why are you using two for:each? I think you should use one for:each in your template.

<template if:true={mapData}>
    <template for:each={mapData} for:item="keyValue">
        <tr key={keyValue.key} class="slds-hint-parent">
            <td scope="col">
                 {keyValue.key}
            </td>               
            <td scope="col">
                    {keyValue.Name}
            </td>                 
            <td scope="col">
                    {keyValue.Email}
            </td>              
            <td scope="col">
                    {keyValue.Phone}
            </td>          
        </tr>      
    </template>
</template>
4
  • No records are displayed every time I use that kind of format.
    – Ertyq
    Commented Jun 9, 2020 at 7:44
  • Can you share a sample of data you have in mapData?
    – Klecool
    Commented Jun 9, 2020 at 7:51
  • these are just available contact records provided by Salesforce in default.
    – Ertyq
    Commented Jun 9, 2020 at 7:57
  • Ok, so your data must be in some sort of object contained in an object or a list. you have to see the structure of mapData
    – Klecool
    Commented Jun 9, 2020 at 8:09
0

While this might not be the complete solution, but one problem in your code is that arrays and objects are not reactive unless their reference is changed, you are pushing the values into the array but not changing the reference. So you need to update the wire method as below.

@wire(getDataFromApex) 
wiredcontactdata({ data, error }) {
    if (data) {
        let newArray = [];
        for(let key in data) {
            if (data.hasOwnProperty(key)) { 
                newArray.push({key: key, value: data[key]});
            }
        }
        this.mapData = newArray; // see the reference is changed.
    } else if (error) {
        window.console.log(error);
    }
}
1
  • i've changed the reference, but same result.
    – Ertyq
    Commented Jun 9, 2020 at 3:43
0

After doing another modifications, I finally got what I am expecting. I distributed values by assigning unique for:item values. Below is the updated html code that works:

<template>  
<table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_col-bordered">
    <thead>
        <tr class="slds-line-height_reset">
            <th class="" scope="col">
                <div class="slds-truncate" title="contactModule">Module</div>
            </th>
            <th class="" scope="col">
                <div class="slds-truncate" title="contactName">Name</div>
            </th>
            <th class="" scope="col">
                <div class="slds-truncate" title="contactEmail">Email</div>
            </th>
            <th class="" scope="col">
                <div class="slds-truncate" title="contactPhone">Phone</div>
            </th> 
        </tr>
    </thead>
    <tbody>
        <template if:true={mapData}>
            <template for:each={mapData} for:item="keyValue">
                <tr key={keyValue.key} class="slds-hint-parent">
                    <th scope="col">
                        <div>{keyValue.key}</div>
                    </th>
                    <th scope="col">
                        <template for:each={keyValue.value} for:item="mapValue">
                            <div key={mapValue.Name}>
                                {mapValue.Name}
                            </div> 
                        </template>
                    </th>
                    <th scope="col">
                        <template for:each={keyValue.value} for:item="mapValue2">
                            <div key={mapValue2.Email}>
                                {mapValue2.Email}
                            </div> 
                        </template>
                    </th>
                    <th scope="col">
                        <template for:each={keyValue.value} for:item="mapValue3">
                            <div key={mapValue3.Phone}>
                                {mapValue3.Phone}
                            </div> 
                        </template>
                    </th>
                </tr>    
            </template>
        </template> 
    </tbody>
</table>

You must log in to answer this question.

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