I have a variable 'contactList' wired to an apex method which will return a list of contact. There is another imperative method will return a list of contact filtered by 'Name' field.
The contact list rendered well after the page init, but after I change the value of 'contactList' by JS, the frontend page didn't display the record list retrieved from apex method.
After click search button the list changed to below, but the contactList are not empty.
Below is code snippet of the code.
--------------------contactList.html----------------------
<template>
<lightning-card>
<div style="display: inline-block" slot='actions'>
<lightning-button label="Search" onclick={searchRecords}></lightning-button>
<lightning-input data-id='searchInputId' style="display: inherit" placeholder='Search By Name' onchange={changeSearchValue} value={searchValue}></lightning-input>
<lightning-button label="New" onclick={showForm}></lightning-button>
</div>
<template for:each={contactList.data} for:item='contact' for:index='itemindex'>
<c-custom-contact-list-item key={contact.Id} contact={contact} if-check={checkAllVar} item-index={itemindex} onitemchecked={modifySelectedList}></c-custom-contact-list-item>
</template>
</lightning-card>
</template>
------------------contactList.js----------------------
import { LightningElement, wire, track } from 'lwc';
import getContactList from '@salesforce/apex/ContactController.getContactList';
import findContacts from '@salesforce/apex/ContactController.findContacts';
import { ShowToastEvent } from 'lightning/platformShowToastEvent'
export default class ContactList extends LightningElement {
@wire(getContactList) contactList;
searchValue = '';
showForm(){
let modalIten = this.template.querySelector('section.slds-modal');
modalIten.classList.add('showModel');
}
changeSearchValue(event){
//console.log(this.searchValue);
this.searchValue = event.target.value;
}
searchRecords(){
console.log(this.searchValue);
findContacts({searchKey : this.searchValue}).then(result => {
console.log(JSON.stringify(result)); // After called this method, the returned value will overwrite this.contactList;
this.contactList = result;
}).catch(error => {
console.log(error);
});
this.template.querySelector('[data-id="searchInputId"]').value = null;
this.searchValue = null;
}
}
--------------------customContactListItem.html-------------------
<template>
<lightning-layout class='list-line'>
<lightning-layout-item class='slds-truncate' style="width: 3.3333333333%" >
<lightning-input type='checkbox' variant='label-hidden' class="listCheckbox" checked={changeCheck} onchange={handleCheck}></lightning-input>
</lightning-layout-item>
<lightning-layout-item class='slds-truncate slds-size_1-of-6 slds-text-align_center'>
<a onclick={openDetail}>{contact.Name}</a>
</lightning-layout-item>
<lightning-layout-item class='slds-truncate slds-size_1-of-6 slds-text-align_center'>
{contact.Phone}
</lightning-layout-item>
<lightning-layout-item class='slds-truncate slds-size_1-of-6 slds-text-align_center'>
{contact.Email}
</lightning-layout-item>
<lightning-layout-item class='slds-truncate slds-size_1-of-6 slds-text-align_center'>
{contact.Title}
</lightning-layout-item>
<lightning-layout-item class='slds-truncate slds-size_1-of-6 slds-text-align_center'>
<img src={contact.Picture__c} width="25px" height="25px"></img>
</lightning-layout-item>
</lightning-layout>
</template>
---------------------------------ContactController.cls------------------------------
public with sharing class ContactController {
@AuraEnabled(cacheable=true)
public static List<Contact> getContactList() {
return [SELECT Id, Name, Title, Phone, Email, Picture__c FROM Contact WHERE Picture__c != null LIMIT 10];
}
@AuraEnabled(cacheable=true)
public static List<Contact> findContacts(String searchKey) {
String key = '%' + searchKey + '%';
List<Contact> list_con = [SELECT Id, Name, Title, Phone, Email, Picture__c FROM Contact WHERE Name LIKE :key AND Picture__c != null LIMIT 10];
System.debug(searchKey);
System.debug(list_con);
return list_con;
}
}
Best Answer
From your console log:
So a wire response in JSON format looks something like
{ "data" : [Your response]}
Now, imperative method response looks like
[ {Your response} ,{Your response}]
In your
searchRecords()
method you are just populating just this.contactListThe markup template:for is expecting the
data
in data attribute.<template for:each={contactList.data}
In your
searchRecords()
method you are just populating justthis.contactList
, not the data attribute ofthis.contactList