I am trying to get the records of some object X using wire service by passing a param to wire service. Below is the code,
searchResults.js
isLoading = false;
boatTypeId = '';
@api
searchBoats(typeId) {
this.notifyLoading(true);
this.boatTypeId = typeId;
}
@wire(getBoats, {boatTypeId: '$boatTypeId'})
wiredBoats(result) {
console.log('wired')
this.boats = result;
if (result.error) {
this.boats = undefined;
this.error = 'Unknown error';
if (Array.isArray(error.body)) {
this.error = error.body.map(e => e.message).join(', ');
} else if (typeof error.body.message === 'string') {
this.error = error.body.message;
}
}
this.notifyLoading(false);
}
notifyLoading(isLoading) {
// dispatch doneLoading or loading events based on the status of isLoading
this.isLoading = isLoading;
if (isLoading) {
const loading = new CustomEvent("loading");
this.dispatchEvent(loading);
} else {
const doneLoading = new CustomEvent("doneloading");
this.dispatchEvent(doneLoading);
}
}
search.js
// Handles loading event
handleLoading() {
this.isLoading = true;
}
// Handles done loading event
handleDoneLoading() {
this.isLoading = false;
}
// Handles search boat event
// This custom event comes from the form
searchBoats(event) {
const searchBoatTypeId = event.detail.boatTypeId;
this.template.querySelector("c-boat-search-results").searchBoats(searchBoatTypeId);
}
search.html
<lightning-layout-item size="12" class="slds-p-top_small slds-is-relative">
<template if:true={isLoading}>
<lightning-spinner alternative-text="Loading"></lightning-spinner>
</template>
<template if:false={isLoading}>
<c-boat-search-results onloading={handleLoading} ondoneloading={handleDoneLoading}>
</c-boat-search-results>
</template>
</lightning-layout-item>
Expectation is when searchBoats
is called from search.js it will display the loading animation by calling this.notifyLoading(true);
(which dispatched loading event handled by search component). And then searchBoats
updates the this.boatTypeId
which in turn should trigger the wire service to get the this.boats
results from getBoats.
What is happening actually is
searchBoats successfully gets called and displays the loading spinner. After that wire service never gets invoked and I get infinite loading spinner (because wire service is never invoked code flow never reaches this.notifyLoading(false)
in the wire call)
If I remove this.notifyLoading(true);
call completely from searchBoats then everything just works fine, which is why it looks like dispatchEvent for loading spinner is blocking the execution of wire service even when the $boatTypeId
value is updated.
Need help understand this behaviour and what is actually causing this to happen. Pretty sure I am doing something wrong here.
Best Answer
There appear to be several issues with this code:
template if:true={isLoading}
.Try the following changes:
searchResults
The searchResults HTML should be updated to show the spinner when isLoading is true, or the actual results otherwise.
search HTML should just do something like:
And have an "id" tracked property in the search component that is set to the value to be searched against by the search results.