Skip to main content
Build the future with Agentforce at TDX in San Francisco or on Salesforce+ on March 5–6. Register now.

Communicate from Child to Parent

Learning Objectives

In this project, you'll:

  • Build Lightning web components that communicate with one another.
  • Communicate from a child component to its parent component.
  • Communicate from a parent component to a child component.
  • Communicate from a component to an unrelated component.

This project is designed for Salesforce developers who have some experience building Lightning web components. If you're not already familiar with Lightning web components, we recommend that you complete some of the badges in the Build Lightning Web Components trail before continuing in this project.

How Components Communicate

When multiple Lightning web components compose an app, we often want those components to share information. How we communicate from one component to another depends on whether and how the components are related. A component inside another component creates a parent-child relationship. How a parent communicates with a child is different from how a child communicates with its parent. And those are both different from how unrelated components (components in separate DOM subtrees) communicate with one another.

Communication types: child-to-parent, parent-to-child, and unrelated components.

In this project, you establish communications between components in each of these relationships. 

Before You Begin

We assume that you have your Salesforce DX development environment set up, and you're comfortable using it to create Lightning web components and deploy them to an org. If you're not familiar with this process yet, complete the Quick Start: Lightning Web Components project before you continue in this project.

Create a New Trailhead Playground

For this project, you need to create a new Trailhead Playground. Scroll to the bottom of this page, click the playground name, then click Create a Trailhead Playground. It typically takes 3–4 minutes to create a new Trailhead Playground. 

Note

Yes, we really mean a brand-new Trailhead playground! If you use an existing org or playground, you can run into problems completing the challenges.

Get Your Trailhead Playground Username and Password

Let's get started. Go to your Trailhead Playground. (If it's not already open, scroll to the bottom of this page and click Launch.) If you see a tab in your org labeled Get Your Login Credentials, great! Skip ahead to step 1. Otherwise, from the App Launcher (App Launcher), find and open Playground Starter and follow the steps.

  1. Click the Get Your Login Credentials tab and take note of your username.
  2. Click Reset My Password. This sends an email to the address associated with your username.
  3. Click the link in the email.
  4. Enter a new password, confirm it, and click Change Password

Set Up Your Project

  1. In Visual Studio Code, create a Salesforce DX project named Event Comms.
  2. Authorize your Trailhead Playground.

Communicate with a Custom Event

Let's start with a simple scenario. A child component dispatches a custom event that triggers an update in the parent component.

A child component named controls is contained by and communicates up to its parent, the numerator component.

When you send an event, you can choose to send some data and you can allow the event to bubble up through the DOM. Let's start with a simple scenario. A child component dispatches a custom event that triggers an update in the parent component.

Communicate from the Controls Component to the Numerator Component

  1. Create a three-region Lightning app page named Event Comms:
    1. In your org (your Trailhead Playground), open Setup.
    2. In the Quick Find box, enter Lightning App Builder and then select Lightning App Builder.
    3. Click New.
    4. With App Page selected, click Next.
    5. For Label, enter Event Comms and then click Next.
    6. Select Three Regions and then click Done.
    7. Click Save, Activate, Save, and Skip and Save.
    8. Click Back to exit Lightning App Builder.
  1. Create the parent Lightning web component named numerator:
    1. In Visual Studio Code, under force-app/main/default, right-click the lwc folder and select SFDX: Create Lightning Web Component.
    2. Enter numerator for the name of the new component.
    3. Press Enter and then press Enter again to accept the default force-app/main/default/lwc.
  1. Code the numerator component files:
    1. In numerator.js, paste this code inside the Numerator class:
        counter = 0;
        handleIncrement() {
          this.counter++;
        }
        handleDecrement() {
          this.counter--;
        }
    2. Save the file.
    3. Open numerator.html and add this code between the template tags:
        <lightning-card title="Numerator" icon-name="action:manage_perm_sets">   
          <p class="slds-text-align_center slds-var-m-vertical_medium">
            Count: <lightning-formatted-number value={counter}></lightning-formatted-number>
          </p>
          <!-- controls go here -->
        </lightning-card>
    4. Save the file.
    5. To make the numerator component available in Lightning app pages, open numerator.js-meta.xml and replace the isExposed tag with these lines:
          <isExposed>true</isExposed>
          <targets>
            <target>lightning__AppPage</target>
          </targets>
    6. Save the file.
  1. Add the numerator component to the Event Comms app:
    1. Right-click the lwc folder and select SFDX: Deploy This Source to Org to deploy the lwc folder to your org.
    2. From the App Launcher (App Launcher) in your playground, find and open Event Comms.
    3. Click Setup and select Edit Page to open the Event Comms app page for editing.
    4. Drag the numerator component (under Custom in the Components list) to the left region of the page.
    5. Click Save.
    6. Click Back to exit Lightning App Builder.
  1. Create and code the child component named controls:
    1. Return to Visual Studio Code and create a Lightning web component named controls.
    2. In controls.js, paste this code inside the Controls class:
        handleAdd() {
          this.dispatchEvent(new CustomEvent('add'));
        }
        handleSubtract() {
          this.dispatchEvent(new CustomEvent('subtract'));
        }
    3. Save the file.
    4. Open controls.html and add this code between the template tags:
        <lightning-card title="Controls" icon-name="action:upload">
          <lightning-layout>
            <lightning-layout-item flexibility="auto" padding="around-small">
              <lightning-button
                label="Subtract"
                icon-name="utility:dash"
                onclick={handleSubtract}>
              </lightning-button>
            </lightning-layout-item>
            <lightning-layout-item flexibility="auto" padding="around-small">
              <!-- buttons go here -->
            </lightning-layout-item>
            <lightning-layout-item flexibility="auto" padding="around-small">
              <lightning-button
                label="Add"
                icon-name="utility:add"
                onclick={handleAdd}
                icon-position="right">
              </lightning-button>
            </lightning-layout-item>
          </lightning-layout>
        </lightning-card>
    5. Save the file.
  1. Add the child component (controls) to the parent component (numerator):
    1. Open numerator.html and replace the controls go here comment with this code:
          <c-controls
            class="slds-show slds-is-relative"
            onadd={handleIncrement}
            onsubtract={handleDecrement}>
          </c-controls>
    2. Save the file.
  1. Verify communications:
    1. To see the changes in Salesforce, deploy the lwc folder and then refresh the Event Comms app page in your Trailhead Playground org.
    2. Click Add and see the count increase.
    3. Click Subtract to see the count decrease.

Now we have a child component (controls) that sends an add event to the parent component (numerator), triggering the handleIncrement function in the parent component (numerator).

Diagram corresponding to the preceding description.

Send Data with the Custom Event

Next let's have the child pass some data with the event to the parent. The business wants to multiply the count. We'll give them more than one option. Use a custom event to pass data from the child to the parent.

  1. Add multiply buttons and a multiply function to the child component (controls):
    1. Open controls.html and replace the buttons go here comment inside the second lightning-layout-item tag with this code:
            <lightning-button
              label="2"
              data-factor="2"
              icon-name="utility:close"
              onclick={handleMultiply}>
            </lightning-button>
            <lightning-button
              label="3"
              data-factor="3"
              icon-name="utility:close"
              onclick={handleMultiply}>
            </lightning-button>
    2. Save the file.
    3. Open controls.js and add this handleMultiply function after the handleSubtract function:
        handleMultiply(event) {
          const factor = event.target.dataset.factor;
          this.dispatchEvent(new CustomEvent('multiply', {
            detail: factor
          }));
        }
      Notice we pass the onclick event to the handleMultiply function, which gets the button data-factor through the event.target.dataset.factor. Then we pass the factor along with the new custom event (multiply) to the parent component (numerator).
    4. Save the file.
  1. Update the parent component (numerator):
    1. Open numerator.html and add this attribute to the c-controls tag:
      onmultiply={handleMultiply}
    2. Save the file.
    3. Open numerator.js and add this handleMultiply function after the handleDecrement function:
        handleMultiply(event) {
          const factor = event.detail;
          this.counter *= factor;
        }
      Here the handleMultiply function gets the onmultiply event passed in and uses its data (event.detail) to update the count (counter).
    4. Save the file.
  1. Verify communications:
    1. To see the changes in Salesforce, deploy the lwc folder and then refresh the Event Comms app.
    2. Click Add and see the count increase.
    3. Click X 2 to see the count multiplied by 2.
    4. Click X 3 to see the count multiplied by 3.

The controls component passes data (data-factor) to its parent (numerator) along with the multiply custom event.

Diagram corresponding to the preceding description.

Allow Custom Events to Bubble

The two multiply buttons were a success. Now the business wants more multiply options. Let's make it easy to add as many buttons as they need. We'll add another Lightning web component for the buttons. To allow the communications to get through, you'll use event bubbling. Bubbling allows the custom event from the button component to bubble up the DOM tree.

  1. Create a component named button:
    1. Create a Lightning web component named button.
    2. In button.js, paste this code inside the Button class:
        @api label;
        @api icon;
        handleButton(event) {
          this.dispatchEvent(new CustomEvent('buttonclick',{
            // bubbles: true
          }));
        }
    3. Import the api decorator from the lwc module.
      import { LightningElement, api } from 'lwc';
    4. Save the file.
    5. Open button.html and add this code between the template tags:
        <lightning-button
          label={label}
          data-factor={label}
          icon-name={icon}
          onclick={handleButton}>
        </lightning-button>
    6. Save the file.
  1. Make the button component a child of the controls component:
    1. Open controls.html and delete the lightning-layout-item that contains two lightning-button tags.
    2. In its place, paste this code:
          <lightning-layout-item flexibility="auto" padding="around-small" onbuttonclick={handleMultiply}>
            <template for:each={factors} for:item="factor">
              <c-button
                key={factor}
                label={factor}
                data-factor={factor}
                icon="utility:close">
              </c-button>
            </template>
          </lightning-layout-item>
      Notice that we moved the handleMultiply function call to the onbuttonclick handler in the lightning-layout-item. This keeps us from adding a handler on every button, resulting in cleaner, faster code.
    3. Save the file.
    4. Open controls.js and add this factors property in the Controls class:
        factors = [0,2,3,4,5,6];
    5. Save the file.
  1. Verify communications:
    1. To see the changes in Salesforce, deploy the lwc folder and then refresh the Event Comms app page.
    2. Click Add and see the count increase.
    3. Click X 2 and notice that nothing happens. Why? By default, a custom event doesn't bubble up past the host.

      [Alt text: Custom event not getting past its container.]
      To allow the event (buttonclick) to bubble up to the lightning-layout-item, we add bubbles: true in the CustomEvent.
    4. Open button.js and uncomment (remove the // before) bubbles: true.

      [Alt text: Custom event now bubbles up past its container.]
    5. Save the file and deploy it again.
    6. Refresh the Event Comms app page.
Note

You may need to refresh the page a couple of times to get the updates through cache and work on the page.

    1. Now click Add to set the count to 1.
    2. Click X 2 to see the count multiplied by 2.
    3. Click X 6 to see the count multiplied by 6.
    4. Click X 0 to reset the count to zero.
    5. Try the following clicks: Add, X 2, X 5, X 2, Add, X 2. Or: Add, X 3, X 2, X 2, Subtract, X 2, Subtract, X 2. Or try your own combination.

Challenge Yourself (optional—we won't check this code)

Add a second instance of the button component in the controls component to create division buttons that appear in the numerator component.

Summary

In this step you established communication from a child component to its parent using a custom event. You passed the event with and without data, and you saw how bubbling affects child-to-parent communications. In the next step you facilitate parent-to-child communications.

Resources

Share your Trailhead feedback over on Salesforce Help.

We'd love to hear about your experience with Trailhead - you can now access the new feedback form anytime from the Salesforce Help site.

Learn More Continue to Share Feedback