Search Here

Pass data to a Child property

  1. Parent-to-Child communication

To enable Parent-to-Child communication, the child component must have a public property or function declared using the @api decorator. 

child.js

import { LightningElement, api } from 'lwc';


export default class Child extends LightningElement {
  @api childVar;
}


child.html

<template>
</template>


parent.html

<template>
  <c-child child-var={parentVar}></c-child>
</template>


parent.js

import { LightningElement } from 'lwc';


export default class Parent extends LightningElement {
  parentVar = 'Hello!';
}

 

Call a Child function

To call a child function, it is necessary to take into account that this can only be done after the child's component has entered the DOM. So in this example I am using the renderedCallback method.

child.js

import { LightningElement, api } from 'lwc';


export default class Child extends LightningElement {
  @api
  childFunction() {
    return 'Hello!';
  }
}


child.html

<template>
</template>


parent.js

import { LightningElement } from 'lwc';


export default class Parent extends LightningElement {
  renderedCallback() {
    let childCmp = this.template.querySelector('c-child');
    let result = childCmp.childFunction();
  }
}


parent.html

<template>
<c-child></c-child>
</template>

 

          2. Child-to-Parent communication

The Child component cannot directly pass data to the Parent component using property, so this can be done by dispatching a custom event from the Child component, and the Parent component must listen for this event. 

Child-to-Parent

child.js

import { LightningElement } from 'lwc';


export default class Child extends LightningElement {
  renderedCallback() {
    this.childFunction();
  }


  childFunction() {
    this.dispatchEvent(new CustomEvent('childevent', {
      detail: {
        childVar: 'Hello!',
      }
    }));
  }
}


child.html

<template>
</template>

 

parent.js

import { LightningElement } from 'lwc';


export default class Parent extends LightningElement {
  parentFunction(event) {
    let result = event.detail.childVar;
  }
}


parent.html

<template>
  <c-child onchildevent={parentFunction}></c-child>
</template>

 

Child-to-Grandparent

When we have a chain of nested components, we often need to pass data from a child component to the grandparent component. So we need to configure Event Propagation using the bubbles property set to true in dispatchEvent on the intermediate components (in our case, it is the Parent component).

child.js

import { LightningElement } from 'lwc';


export default class Child extends LightningElement {
  renderedCallback() {
    this.childFunction();
  }


  childFunction() {
    this.dispatchEvent(new CustomEvent('childevent', {
      detail: {
        childVar: 'Hello!',
      }
    }));
  }
}


child.html

<template>
</template>


parent.js

import { LightningElement } from 'lwc';


export default class Parent extends LightningElement {
  parentFunction(event) {
    this.dispatchEvent(new CustomEvent('parentevent', {
      bubbles: true,
      detail: event.detail
    }));
  }
}


parent.html

<template>
  <c-child onchildevent={parentFunction}></c-child>
</template>

 

grandparent.js

import { LightningElement } from 'lwc';


export default class Grandparent extends LightningElement {
  grandparentFunction(event) {
    let result = event.detail.childVar;
  }
}


grandparent.html

<template>
  <c-parent onparentevent={grandparentFunction}></c-parent>
</template>

 

3. Communication between unrelated components

MyMessageChannel.messageChannel-meta.xml

<?xml version="1.0" encoding="UTF-8" ?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
  <masterLabel>MyMessageChannel</masterLabel>
  <isExposed>true</isExposed>
  <description>Sends messages to unrelated components</description>
  <lightningMessageFields>
    <fieldName>value</fieldName>
    <description>The value to send to a component</description>
  </lightningMessageFields>
</LightningMessageChannel>

 

Then create 2 unrelated components. The first has an input field and publishes value from the field via the Message Channel. The second subscribes to this Message Channel and displays the value.

component1.html

<template>
  <lightning-input onchange={sendMessage}></lightning-input>
</template>


component1.js

import { LightningElement, wire } from 'lwc';
import { publish, MessageContext } from 'lightning/messageService';
import MY_MESSAGE_CHANNEL from '@salesforce/messageChannel/MyMessageChannel__c';


export default class Component1 extends LightningElement {
  @wire(MessageContext)
  messageContext;


  sendMessage(event) {
    const payload = {
      value: event.target.value,
    };
    publish(this.messageContext, MY_MESSAGE_CHANNEL, payload);
  }
}


component2.html

<template>
  <p>{value}</p>
</template>

 

component2.js

import { LightningElement, wire } from 'lwc';
import { subscribe, MessageContext } from 'lightning/messageService';
import MY_MESSAGE_CHANNEL from '@salesforce/messageChannel/MyMessageChannel__c';


export default class Component1 extends LightningElement {
  value;
  subscription;


  @wire(MessageContext)
  messageContext;


  connectedCallback() {
    this.subscribeToMessageChannel();
  }


  subscribeToMessageChannel() {
    this.subscription = subscribe(
      this.messageContext,
      MY_MESSAGE_CHANNEL,
      (message) => this.handleMessage(message)
    );
  }


  handleMessage(message) {
    this.value = message.value;
  }
}

 

Post a Comment

0 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.