0

I have a picklist and when it is updated, it calls an Apex method to fetch new values for the child to render. However, the child component only loads initially when the page is rendered. After, when I change the picklist value, the child never is reredered/updated to show the new values. The updated values are in the parent connectedCallback but the child component itself does not display the updated values.

PARENT LWC

    <lightning-accordion class="accordian" allow-multiple-sections-open
        active-section-name={activeSections}>
        <lightning-accordion-section name="Option1" label="Option1">
            <c-child products={arr1} brand={opportunity.Brand__c}
                onselected={handleOption1Selected} onamountchanged={handleOption1SelectedChanged}
                type={opportunity.Type}>
            </c-child>
        </lightning-accordion-section>

        <lightning-accordion-section name="Option2" label="Option2">
            <c-child products={arr2} onselected={handleOption2Selected}
                onamountchanged={handleOption2SelectedChanged} type={opportunity.Type}>
            </c-child>
        </lightning-accordion-section>
    </lightning-accordion>

PARENT JS

    @track arr1 = [];
    @track arr2 = [];
    opportunityId;
    @track opportunity = {};

    connectedCallback() {
        this.productSelection();
    }

    handleBrandChange(event) {
        this.opportunity.Brand__c = event.detail.value;
        this.productSelection(); // call apex to update values (HTML Ommited)
    }

    productSelection() {
        Promise.all([
            getProductSelection({
                opportunityId: this.opportunityId,
                brand: this.opportunity.Brand__c 
            }),
        ])
            .then(result => {
                //set values ... 
                this.initializeProducts(result);

            })
            .catch(error => {
                //error handling ...
            })
    }

    initializeProducts(allProducts) {
        //updated array information from apex method
        let tempArr1 = [];
        let tempArr2 = [];
        for (let i = 0; i < allProducts.length; i++) {
            if (allProducts[i].Product.Brand__c === 'Option1') {
                tempArr1.push(allProducts[i]);
            }
            if (allProducts[i].Product.Brand__c === 'Option2') {
                tempArr2.push(allProducts[i]);
            }
        }
        this.arr1 = tempArr1;
        this.arr2 = tempArr2; 
    }

APEX:

    @AuraEnabled
    public static Opportunity_ProductSelection getProductSelection(Id opportunityId, String brand){
        List<Opportunity_ProductSelection> productSelection = new List<Opportunity_ProductSelection>();
        productSelection.add( new Opportunity_ProductSelection(
            product.Id,
            // values ...
            newRenewal // what I am changing based on picklist option brand
        ));
        return productSelection;
    }

CHILD LWC: /* Not being Called and updated with new brand and array values */

    @api set brand(value) {
        this.brandSelected = [...value];
    }
    get brand() {
        return this.brandSelected;
    }
    brandSelected;

    connectedCallback() {
        this.brandSelected = Object.assign({}, this.brand);
        window.console.log('CHILD BRAND: ', this.brandSelected);
    }

Interestingly I added some console logs (in Parent JS initializeProducts() ) and the temparr are populated but when I assign them to this.temparr they are empty:

enter image description here

4
  • try to add @wire decorator to your opportunity attribute. you are passing the object attribute to your child cmp and wire should ensure that any update of the opportunity will be re-rendered.
    – Damecek
    Commented Mar 7, 2022 at 11:09
  • Opportunity already has @track on it. Just updated the code. Do you have any other suggestions? I think I'm out of ideas
    – some guy
    Commented Mar 7, 2022 at 11:14
  • 1
    where are your tempArr1 & tempArr2 getting set ? As per me your both arr1 and arr2 must be getting set to undefined.
    – Elijah
    Commented Mar 7, 2022 at 11:23
  • Updated the code. tempArr are set from the apex result
    – some guy
    Commented Mar 7, 2022 at 11:47

1 Answer 1

1

Well , I don't know why it doesn't work

As per your code Track should work.

@track title;


this.title =  this.title;

Even though you do like this (change the variable to the same ) track still should work

But since I can't find why it doesn't work

A workaround that I would suggest is

<template if:true = {toggleComponent}
//child component
 </template>

In JS , where you wanted the child to be rendered


this.toggleComponent = false;
        setTimeout(()=>{
            this.toggleComponent = true;
          }, 0.1);

This has worked for me in most places.

Since the toogleComponent is a simple boolean variable , it is a primitive type. As per Salesforce Documenatation , primitive type variables are by default reactive and so they render when changed

NOTE: You can think like why use setTimeout ,we can directly use as follows,

this.toggleComponent = false;
this.toggleComponent = true;

thinking it should render the component,

But that too didn't work I have tried it for some of my tasks

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .