So I have situation where my Parent gets info from Child Component 1 and passes that to Child Component 2. Getting from Child Component 1 to Parent is okay as per console.log(), but my Child Component 2 does not re-render after the value is changed on Parent. Furthermore, my Child component 2 only renders correctly if I use @track, if I put @api it doesnt "call" @wire and I have an empty datable.
Here is my Parent html:
<template>
<lightning-card>
<c-search-by-network-or-country onsearchcountryornetwork={searchByNetworkOrCountryHandler}></c-search-by-network-or-country>
</lightning-card>
<lightning-card class="slds-m-top_medium">
<c-display-networks country-text-search={countryFromSearch} network-text-search={networkFromSearch}></c-display-networks>
</lightning-card>
</template>
Parent js:
import { LightningElement,api,track } from 'lwc';
export default class ParentComponent extends LightningElement {
@api countryFromSearch;
@api networkFromSearch;
searchByNetworkOrCountryHandler(event){
this.networkFromSearch = event.detail.NetworkText;
this.countryFromSearch = event.detail.CountryText;
console.log('searchedNetwork' + this.networkFromSearch);
}
}
Child Component 1 js:
import { LightningElement,api } from 'lwc';
export default class SearchByNetworkOrCountry extends LightningElement {
@api countryText;
@api networkText;
countryChangeHandler(event){
this.countryText = event.target.value;
}
networkChangeHandler(event){
this.networkText = event.target.value;
}
searchClickHandler(){
console.log('called');
const newEvent=new CustomEvent('searchcountryornetwork',{
detail:{
NetworkText:this.networkText,
CountryText:this.countryText
}
});
console.log('event' + newEvent);
this.dispatchEvent(newEvent);
}
}
Child Component 2 js:
export default class DisplayNetworks extends LightningElement {
@track networkTextSearch='';
@track countryTextSearch='';
columns = columns;
@wire(getJsonData,{insertCountryText:'$countryTextSearch',insertNetworkText:'$networkTextSearch'})
parsedDataFromApex;
constructor(){
super();
console.log('networkTextSearch' + this.networkTextSearch);
}
}
My Apex class:
@AuraEnabled(cacheable=true)
public static List<JsonParserController> getJsonData(String insertCountryText,String insertNetworkText) {
StaticResource jsonData = [SELECT Body FROM StaticResource WHERE Name = 'jsonDataNetworks'];
String jsonString = jsonData.Body.toString();
List<JsonParserController> parsedData = (List<JsonParserController>) System.JSON.deserialize(jsonString, List<JsonParserController>.class);
if (!String.isEmpty(insertCountryText) && !String.isEmpty(insertNetworkText)) {
parsedData = filterByCountryAndNetwork(parsedData, insertCountryText, insertNetworkText);
}
else if (!String.isEmpty(insertCountryText)) {
parsedData = filterByCountry(parsedData, insertCountryText);
}
else if (!String.isEmpty(insertNetworkText)) {
parsedData = filterByNetwork(parsedData, insertNetworkText);
}
System.debug('now called' + parsedData);
return parsedData;
}
Best Answer
@api properties are read-only in a component, and @track properties are not publicly accessible. Unlike Aura, data bindings are only one way, from parent to child.