brief app structure(see image): "Line item" child components list on the right (just one 1601xCC5Bulk on this pic), container with pallets on the left. <<Allocate btn opens another child modal with a form (if:true..) this form's picklist uses @wire apex to show only empty pallets, so it's refreshed by form's controller itself after DML.
problem arises when changing amount of pallets by a parent for example, using red button on the right. this DML deletes the container along with pallets.
But if the hidden form gets opened again, old pallet values are still present as picklist values, i need to refresh that data. but this child is hidden, so unreachable by standard: parent -> querySelector(child2).method()
- Sorry for newb question: Is there a way to access hidden component's methods?
- I was also thinking of moving the call to Apex query up to the parent component (easy to trigger), then passing it down to child modal as an api argument, so when modal appears it'll get updated data. this feels a bit wrong to do, as parent lifts child's burden.(maybe i'm wrong)
- I was also thinking of using child's renderedCallback for that apex query, but afraid of infinite render loops?
- Disabling caching of auraEnabled apex would be a nice thing, but seems impossible.
Here is the bare bones markup, showing only all involved parts
===PARENT (with 2 children)===
HTML
<template for:each={lineItems.data} for:item="lineItem">
<lightning-layout-item key={lineItem.Id} size="12">
<c-packing-list-line-item-card lineitem={lineItem} onallocatebuttonpress={openAllocationModal}></c-packing-list-line-item-card>
</lightning-layout-item>
</template>
<template if:true={isLineItemModalOpen}>
<c-packing-list-allocation-modal recordid={recordId} oncloseallocationmodal={closeAllocModal} onproductallocated={refreshData}></c-packing-list-allocation-modal>
</template>
JS
openAllocationModal(e) {
this.editItemId = e.detail;
this.isLineItemModalOpen = true;
}
closeAllocModal() {
this.isLineItemModalOpen = false;
}
===CHILD 1: packing-list-line-item-card=== (the one on the right, showing product details, passes id to modal)
HTML
<lightning-button variant="brand" label="<< Allocate" data-itemid={lineitem.Id} onclick={openAllocationModal}></lightning-button>
JS
openAllocationModal(e) {
const selectEvent = new CustomEvent('allocatebuttonpress', { detail: e.target.dataset.itemid });
this.dispatchEvent(selectEvent);
}
===CHILD 2: Allocation Modal (conditional display)===
HTML
<template if:true={showInsertButton}>
<button class="slds-button slds-button_brand" onclick={handleAllocationInsert}>Insert</button>
</template>
JS (you are probably only interested in closeModal(){}, other stuff is for completeness)
handleAllocationInsert() {
[...]
createRecord(recordInput)
.then((allocId) => {
this.showToast('success', 'Success', 'Product Allocated');
this.handleInsert(this.palletValue);
this.refreshPallets();
})
.catch((error) => {
this.showToast('error', 'Error creating record', error.body.message);
this.closeModal();
});
}
closeModal() {
// On save parent closes modal
console.log('closing 1');
const selectEvent = new CustomEvent('closeallocationmodal');
this.dispatchEvent(selectEvent);
this.spinner = false;
}
handleInsert(palletValue) {
// On save parent refreshes container view
const selectEvent = new CustomEvent('productallocated', {
detail: this.palletcontainers[palletValue].containerId
});
this.dispatchEvent(selectEvent);
this.closeModal();
}