Project: Contact Management Application
By the end of this lesson, you'll be able to:
- Pass an Account context from a parent to a Contact-list child component
- Create and delete Contacts scoped to that Account
- Navigate to a Contact's record page from the list
Prerequisites: "Project: Account Search Tool"
What We're Building
A parent accountDetail component passing its recordId down to a child contactList component (Module 5's @api pattern), which lists, creates, deletes, and navigates to Contacts scoped to that Account.
The Child Component
// contactList.js
import { LightningElement, api, wire } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';
import { createRecord, deleteRecord } from 'lightning/uiRecordApi';
import { refreshApex } from '@salesforce/apex';
import getContactsForAccount from '@salesforce/apex/ContactController.getContactsForAccount';
import CONTACT_OBJECT from '@salesforce/schema/Contact';
import LAST_NAME_FIELD from '@salesforce/schema/Contact.LastName';
import ACCOUNT_FIELD from '@salesforce/schema/Contact.AccountId';
export default class ContactList extends NavigationMixin(LightningElement) {
@api accountId;
wiredContactsResult;
@wire(getContactsForAccount, { accountId: '$accountId' })
wiredContacts(result) {
this.wiredContactsResult = result;
}
get contacts() {
return this.wiredContactsResult?.data ?? [];
}
handleViewContact(event) {
this[NavigationMixin.Navigate]({
type: 'standard__recordPage',
attributes: {
recordId: event.currentTarget.dataset.id,
objectApiName: 'Contact',
actionName: 'view',
},
});
}
async handleAddContact(lastName) {
await createRecord({
apiName: CONTACT_OBJECT.objectApiName,
fields: {
[LAST_NAME_FIELD.fieldApiName]: lastName,
[ACCOUNT_FIELD.fieldApiName]: this.accountId,
},
});
await refreshApex(this.wiredContactsResult);
}
async handleDeleteContact(contactId) {
await deleteRecord(contactId);
await refreshApex(this.wiredContactsResult);
}
}
accountId: '$accountId' (Module 6) makes the wire re-fetch automatically if a parent ever swaps to a different Account entirely — the reactive parameter pattern applied to a value received from a parent, not just a local property.
Exercise
Write the parent template markup passing recordId into contactList's accountId property.
Show hint
Recall Module 5's @api property-passing syntax.
Exercise
Challenge: explain, as a comment, why ACCOUNT_FIELD is included in the createRecord fields for a new Contact.
Show hint
Think about what actually associates the new Contact with its parent Account.
Project: Contact Management Application Quiz
My Notes
Log in to keep private notes on this lesson.
Questions about this lesson
No questions yet — be the first to ask.
Log in to ask a question about this lesson.
Summary
A parent Account context flows down to a child Contact list via @api, tying Module 5's communication pattern together with LDS create/delete and Module 9's navigation.