Start tracking your progress
Trailhead Home
Trailhead Home

Create a Child Component and Interact with It

Our code base has grown in the previous steps. Let’s now take a minute to refactor our bear list component into several smaller components. We are going to move the code of bear tiles into a new component.

Create the Bear Tile Component

  1. In VS Code, right-click the lwc folder and click SFDX: Create Lightning Web Component.
  2. Name the component bearTile.
  3. Open bearList.html and cut all the code between <!-- Start bear tile --> and <!-- End bear tile -->.
  4. Paste the code within the template tags of bearTile.html. Once you’re done, bearTile.html should look like this.
    <template>
    	<lightning-card title={bear.Name} class="bear-tile">
    		<div class="slds-var-p-horizontal_small bear-tile-body">
    			<div class="slds-media">
    				<div class="slds-media__figure">
    					<img src={appResources.bearSilhouette} alt="Bear profile" class="bear-silhouette"/>
    				</div>
    				<div class="slds-media__body">
    					<p class="slds-var-m-bottom_xx-small">{bear.Sex__c}</p>
    					<p class="slds-var-m-bottom_xx-small">{bear.Age__c} years old</p>
    					<p class="slds-var-m-bottom_xx-small">{bear.Height__c} cm</p>
    					<p class="slds-var-m-bottom_xx-small">{bear.Weight__c} Kg</p>
    				</div>
    			</div>
    		</div>
    	</lightning-card>
    </template>
  5. Replace the contents of bearTile.js with:
    import { LightningElement, api } from 'lwc';
    import ursusResources from '@salesforce/resourceUrl/ursus_park';
    export default class BearTile extends LightningElement {
    	@api bear;
    	appResources = {
    		bearSilhouette: `${ursusResources}/img/standing-bear-silhouette.png`,
    	};
    }
    We added a bear property decorated with @api. This exposes the bear property to any parent component.
  6. Delete bearList.css.
  7. Create a new bearTile.css file in the bearTile directory and paste the following code into the file.
    .bear-tile {
      border: 1px solid #d2955d;
      background-color: #fae8d2;
      border-radius: .25rem;
      display: block;
    }
    .bear-silhouette {
      height: 100px;
    }
    .bear-tile-body {
      background: linear-gradient(180deg, rgba(255,255,255,1) 80%, #fae8d2 100%);
    }
  8. Open bearList.html and replace the <!-- Start bear tile --> and <!-- End bear tile --> comments with <c-bear-tile bear={bear}></c-bear-tile>. Once you are done, bearList.html should look like this.
    <template>
    	<lightning-card title="Bears" icon-name="utility:animal_and_nature">
    		<div class="slds-card__body_inner">
    			<!-- Start bear list -->
    			<template if:true={bears.data}>
    				<lightning-input type="search"
    					onchange={handleSearchTermChange}
    					variant="label-hidden"
    					class="slds-var-m-bottom_small"
    					label="Search"
    					placeholder="Search for bears"
    					value={searchTerm}>
    				</lightning-input>
    				<lightning-layout multiple-rows="true" pull-to-boundary="small">
    					<template for:each={bears.data} for:item="bear">
    						<lightning-layout-item key={bear.Id} size="3" class="slds-var-p-around_x-small">
    							<c-bear-tile bear={bear}></c-bear-tile>
    						</lightning-layout-item>
    					</template>
    				</lightning-layout>
    				<!-- No bears found -->
    				<template if:false={hasResults}>
    					<div class="slds-align_absolute-center slds-var-m-vertical_small">
    						This is beary disturbing, we did not find results...
    					</div>
    				</template>
    			</template>
    			<!-- End bear list -->
    			<!-- Data failed to load -->
    			<template if:true={bears.error}>
    				<div class="slds-text-color_error">
    					An error occurred while loading the bear list
    				</div>
    			</template>
    		</div>
    	</lightning-card>
    </template>
    This references our bear tile component with the bear attribute that we defined in the previous steps. Notice that our component folder and files are named bearTile, but the tag we added is c-bear-tile. The starting c represents the default namespace, appended with the name of the component in lowercase, with dashes separating what use to be capital letters.
  9. Deploy the updated code to the org and test your new list component. It should look better with a subtle gradient.

Bear list with custom style on the Ursus Park Home page

Interact with the Bear List Component

Rangers are requesting the ability to quickly look at a bear record and edit it without having to navigate away from the homepage. Let's make bear tiles clickable and open an editable bear record form.

  1. Edit bearTile.html and add the following code after the <lightning-card title={bear.Name} class="bear-tile"> tag.
    <div slot="actions">
    	<lightning-button-icon
    		icon-name="utility:search"
    		icon-class="bear-tile-button"
    		variant="bare"
    		alternative-text="Open record"
    		onclick={handleOpenRecordClick}>
    	</lightning-button-icon>
    </div>
    We added an edit button that fires the handleOpenRecordClick function. The button is placed on the lightning card using the actions slot. A slot is a placeholder for markup that a parent component passes into a component’s body.
  2. Edit bearTile.js and add the following function before the last closing bracket.
    handleOpenRecordClick() {
    	const selectEvent = new CustomEvent('bearview', {
    		detail: this.bear.Id
    	});
    	this.dispatchEvent(selectEvent);
    }
    Code highlights:
    • The handleOpenRecordClick function is called when a user clicks on the open record button of a bear tile.
    • The function creates and fires a custom bearview event that holds the bear record id.
  3. Edit bearList.html and add an onbearview={handleBearView} attribute to the c-bear-tile tag. This allows us to capture the bearview event that is fired by the tile component. The event is handled in a handleBearView function.
    <c-bear-tile bear={bear} onbearview={handleBearView}></c-bear-tile>
  4. Replace the contents of bearList.js with:
    import { NavigationMixin } from 'lightning/navigation';
    import { LightningElement, wire } from 'lwc';
    /** BearController.searchBears(searchTerm) Apex method */
    import searchBears from '@salesforce/apex/BearController.searchBears';
    export default class BearList extends NavigationMixin(LightningElement) {
    	searchTerm = '';
    	@wire(searchBears, {searchTerm: '$searchTerm'})
    	bears;
    	handleSearchTermChange(event) {
    		// Debouncing this method: do not update the reactive property as
    		// long as this function is being called within a delay of 300 ms.
    		// This is to avoid a very large number of Apex method calls.
    		window.clearTimeout(this.delayTimeout);
    		const searchTerm = event.target.value;
    		// eslint-disable-next-line @lwc/lwc/no-async-operation
    		this.delayTimeout = setTimeout(() => {
    			this.searchTerm = searchTerm;
    		}, 300);
    	}
    	get hasResults() {
    		return (this.bears.data.length > 0);
    	}
    	handleBearView(event) {
    		// Get bear record id from bearview event
    		const bearId = event.detail;
    		// Navigate to bear record page
    		this[NavigationMixin.Navigate]({
    			type: 'standard__recordPage',
    			attributes: {
    				recordId: bearId,
    				objectApiName: 'Bear__c',
    				actionName: 'view',
    			},
    		});
    	}
    }
    Code highlights:
    • We import a navigation mixin that bundles utility functions dealing with navigation. A mixin lets us add functionality to a class without extending it. This is useful when a class already extends a parent class (a class can only extend a single parent).
    • Our class extends the navigation mixin applied to the LightningElement base class.
    • We handle the bearview event in the handleBearView function. We extract the bear record id from the event detail and we use the navigation mixin to navigate to a bear record page.
  5. Deploy the updated code to the org and test that you can navigate to a bear record with the button icon on a tile.

That’s it for this step. We’ve refactored our component into two smaller components: the bear list and a bear tile. We’ve explored how to communicate from the parent list component to the child tile component with an @api decorator. We also saw how to communicate from a child to a parent with a custom event.

In the next step, we see how to interact with other components in a Lightning page.