I have created boatSearchResults LWC as per the recommendation but yet I couldn't complete the challenge and I couldn't find exactly what's the problem.
Here is my code
boatSearchResults.html
<template>
<template if:true={boats}>
<lightning-tabset variant="scoped">
<lightning-tab label="Gallery">
<div class="slds-scrollable_y">
<!-- layout horizontally aligned to the center -->
<!-- layout allowing multiple rows -->
<lightning-layout horizontal-align="center" multiple-rows>
<!-- template looping through each boat -->
<template for:each={boats} for:item="boat">
<!-- lightning-layout-item for each boat -->
<lightning-layout-item class="slds-var-p-horizontal_xx-small" padding="around-small" flexibility="auto" size="12" small-device-size="6" medium-device-size="4" large-device-size="3" key={boat.Id}>
<!-- Each BoatTile goes here -->
<c-boat-tile boat={boat} selected-boat-id={selectedBoatId} onboatselect={updateSelectedTile}></c-boat-tile>
</lightning-layout-item>
</template>
</lightning-layout>
</div>
</lightning-tab>
<lightning-tab label="Boat Editor">
<!-- Scrollable div and lightning datatable go here -->
<div class="slds-scrollable_y">
<lightning-datatable
key-field="Id"
data={boats}
draft-values={draftValues}
columns={columns}
onsave={handleSave}
is-loading={isLoading}
hide-checkbox-column>
</lightning-datatable>
</div>
</lightning-tab>
<lightning-tab label="Boats Near Me">
<!-- boatsNearMe component goes here -->
<c-boats-near-me boat-type-id={boatTypeId}></c-boats-near-me>
</lightning-tab>
</lightning-tabset>
</template>
</template>
-----------------------------------------------------------------------------------------------------
boatSearchResults.js
import { LightningElement, wire, track, api } from 'lwc';
import { MessageContext, publish } from 'lightning/messageService';
import {refreshApex} from '@salesforce/apex';
import {updateRecord} from 'lightning/uiRecordApi';
import {ShowToastEvent} from 'lightning/platformShowToastEvent';
import getBoats from '@salesforce/apex/BoatDataService.getBoats'
import BOATMC from '@salesforce/messageChannel/BoatMessageChannel__c'
// ...
const SUCCESS_TITLE = 'Success';
const MESSAGE_SHIP_IT = 'Ship it!';
const SUCCESS_VARIANT = 'success';
const ERROR_TITLE = 'Error';
const ERROR_VARIANT = 'error';
const COLUMNS = [
{ label: 'Name', fieldName: 'Name', editable: true },
{ label: 'Length', fieldName: 'Length__c', type: 'number', editable: true },
{ label: 'Price', fieldName: 'Price__c', type: 'currency', editable: true },
{ label: 'Description', fieldName: 'Description__c', editable: true }
];
export default class BoatSearchResults extends LightningElement {
@api selectedBoatId;
@api boatTypeId;
@track boats;
isLoading = false;
@track draftValues = [];
columns = COLUMNS;
// wired message context
@wire(MessageContext) messageContext;
// wired getBoats method
@wire(getBoats,{boatTypeId: '$boatTypeId'})
wiredBoats({error,data}) {
if(data){
this.boats = data;
console.log('boatSearchResults.wiredBoats'+this.boatTypeId);
console.log('boatSearchResults.wiredBoats'+data.value);
this.notifyLoading(false);
}else if (error){
this.error = error;
this.notifyLoading(false);
}
}
// public function that updates the existing boatTypeId property
// uses notifyLoading
@api searchBoats(boatTypeId) {
this.boatTypeId = boatTypeId;
this.notifyLoading(true);
console.log(this.boatTypeId +', '+ boatTypeId);
}
// this public function must refresh the boats asynchronously
// uses notifyLoading
@api async refresh(){
this.notifyLoading(true);
await refreshApex(this.boats);
console.log('boatSearchResults.refresh'+this.boats);
this.notifyLoading(false);
}
// this function must update selectedBoatId and call sendMessageService
updateSelectedTile(event) {
this.selectedBoatId = event.detail.boatId;
this.sendMessageService(this.selectedBoatId);
}
// Publishes the selected boat Id on the BoatMC.
sendMessageService(boatId) {
// explicitly pass boatId to the parameter recordId
const message ={
recordId: boatId
};
console.log(message);
publish(this.messageContext, BOATMC, message);
}
// This method must save the changes in the Boat Editor
// Show a toast message with the title
// clear lightning-datatable draft values
handleSave(event) {
const recordInputs = event.detail.draftValues.slice().map(draft => {
const fields = Object.assign({}, draft);
return { fields };
});
const promises = recordInputs.map(recordInput =>
//update boat record
updateRecord(recordInput)
);
Promise.all(promises)
.then(() => {
const toastEvent = new ShowToastEvent({
title:SUCCESS_TITLE,
message:MESSAGE_SHIP_IT,
variant:SUCCESS_VARIANT
})
this.dispatchEvent(toastEvent);
this.draftValues = [];
this.refresh();
})
.catch(error => {
const toastEvent = new ShowToastEvent({
title:ERROR_TITLE,
message: error.body.message,
variant: ERROR_VARIANT
})
this.dispatchEvent(toastEvent);
})
.finally(() => {
console.log('draftValues Cleared'+this.draftValues);
});
}
// Check the current value of isLoading before dispatching the doneloading or loading custom event
notifyLoading(isLoading) {
let status = isLoading ? 'loading' : 'doneloading';
const loadEvent = new CustomEvent(status);
this.dispatchEvent(loadEvent);
}
}
I have searched everywhere I was able to, but none fixed the issue that I am getting. Hope I would get the exact problem here. Thanks in advance.
#Lightning Web Components #LWC #LWC Superbadge Challenge #LWC Component #LWC Development #LWC Trailmix #LWCblogs #Salesforce Developer #JavaScript Certification #Trailhead
#Lightning Web Components #LWC #LWC Superbadge Challenge #LWC Component #LWC Development #LWC Trailmix #LWCblogs #Salesforce Developer #JavaScript Certification #Trailhead
Hi Shankar,
In the handleSave() method you should be using updateBoatList method to update the records instead of standard updateRecord.
Also add the below import statement
import updateBoatList from '@salesforce/apex/BoatDataService.updateBoatList';