[SalesForce] Reload a child component based on onclick action event from parent in lightning web component

I need some guidance.
I have a parent and a child component.
The parent component is a custom chatter publisher, which creates a case comment.
The child component is a custom chatter feed, which should display the list of feeds.
The idea is on the button click of the publisher(parent), the chatter feed(child) should reload itself, to display the latest comment.
I think I will have to do something on the handleOnPost(event){} in the parent.js, not sure how to achieve.
enter image description here
Code below:

Parent.html

<template>
    <lightning-card title="Post Comment">
    <div class="slds-p-around_small">
        <lightning-textarea
            name="feed"
            value={chatterComment}
            label="Post your comment here."
            max-length="300"
            onchange={handleChangeEvent}>
     </lightning-textarea>
            <lightning-button data-key={recordId} label="Comment" onclick={handleOnPost} variant="base" class="slds-m-left_x-small"></lightning-button>
        <!-- Insert child component-->
        <c-my-network-get-chatter-feed 
        record-id={recordId}
        record-count={recordCount} >
    </c-my-network-get-chatter-feed>
    </div>
</lightning-card>
</template>

Parent.Js

    import { LightningElement, api, track, wire } from 'lwc';import postNotification from '@salesforce/apex/myNetworkGetChatterFeeds.postNotification';export default class MyNetworkChatterPublisher extends LightningElement {
    @api recordId;
    @api recordCount;
    @track chatterComment;

    @track feed;
    @track error;
    handleChangeEvent(event)
    {
       this.chatterComment=event.target.value;
    }
    handleOnPost(event){
        postNotification({
            recordId: event.currentTarget.dataset.key , 
            messageBody: this.chatterComment});
        //i think i need to call child method here, how to do that?
        debugger;
    }
}

Child.html

<template>
    <lightning-card title="Chatter Feed"> 
      <div class="slds-m-around_medium">
        <template if:true={feed}>
            <template for:each={feed} for:item="element">
              <lightning:card key={element.Id}>
              <div class="slds-media slds-no-space slds-grow" >
              <div class="slds-media__figure" >
                <span class="slds-avatar slds-avatar_medium">
                  <lightning:avatar class="slds-avatar slds-avatar_medium slds-avatar_circle">
                    <img src="/sfsites/c/profilephoto/005/T" alt="Default profile pic in communities"></lightning:avatar>
                </span>
              </div>
              <div class="slds-media__body" key={element.Id}>
                <p>{element.postComment}</p>
                <p>{element.feed.InsertedBy.Name}</p>
                <p>{element.feedCreatedDate}</p>
              </div>
            </div><br/><br/>
            </lightning:card>
                </template>
        </template>         
      </div>
   </lightning-card>
</template>

Child.js

    import { LightningElement, api, wire, track } from 'lwc';import getFeedElements from '@salesforce/apex/myNetworkGetChatterFeeds.getFeedElements';export default class MyNetworkGetChatterFeed extends LightningElement {
@api recordId;

@track feed;
@track error;

@wire(getFeedElements,{recordId: '$recordId'}) 
feedElements({ error, data }) {
    if (data) {
        this.feed = data;
        this.error = undefined;
    } else if (error) {
        this.error = error;
        this.feed = undefined;
    }
};
@api
loadFeed()
{
    getFeedElements({recordId: this.recordId})
        .then(results => {
            this.feed = results;
            this.error = undefined;
            window.console.log('data fetched  from child component' + this.feed);
        })
        .catch(error => {
            this.error = error;
            this.feed = undefined;
            console.log('i am in error');
        });

}

}

I have revised child.js, see above
After adding a public method to the child.js, my new parent onclick handler looks like below

handleOnPost(event){
    postNotification({
        recordId: event.currentTarget.dataset.key , 
        messageBody: this.chatterComment});
        this.template.querySelector('c-my-network-get-chatter-feed').loadFeed();

}

From the chrome, console I can see that the method is called and executed.image below

The problem that I still have is, the child component doesn't reload on the button click.
How do I reload child.html on button click, does the public method needs to return some value, so that the <template if:true={**feed**}> gets the desired value.

enter image description here

Best Answer

You can define a public method in the child component and call that in the parent.

Firstly change your wired method as below:

@wire(getFeedElements,{recordId: '$recordId'}) 
feedElements(value) {
    this.wiredFeedElements = value;
    let { error, data } = value;
    if (data) {
        this.feed = data;
        this.error = undefined;
    } else if (error) {
        this.error = error;
        this.feed = undefined;
    }
};

Import the refreshApex method in the child component.

import {refreshApex} from '@salesforce/apex';

Define the @api method in the child. You need to use a refresh apex method here.

@api
childMethod() {
     if(this.wiredFeedElements){
          refreshApex(this.wiredFeedElements);
     }
}

This is how you can call it in the parent.

this.template.querySelector('c-my-network-get-chatter-feed').childMethod();

Refer @api Method

Refer refreshApex method

Related Topic