How to Query Related Contacts from an Account in Salesforce
Salesforce developers and tech leads often work with different object which are related to each other in different ways (many to many, one to many etc). It can be tricky for new Salesforce Developers to build subqueries using soql. In today’s article we will pickup Account and Contact to address this and learn how to query related contacts form an Account in Salesforce.
Table of Contents
- Introduction to Account-Contact Relationship in Salesforce
- Understanding SOQL for Related Records
- Anatomy of a subquery in SOQL
- Querying Related Contacts Using Apex
- Querying Related Contacts Using JavaScript in LWC
- Best Practices for Querying Related Data in Salesforce
Introduction to Account-Contact Relationship in Salesforce
In Salesforce, the relationship between Accounts and Contacts is a standard parent-child one to many relationship. An Account can have multiple Contact and each Contact is associated with an Account via the AccountId
field.
Understanding relationships between objects is the first step to build an efficient SOQL.
Understanding SOQL for Related Records
SOQL (Salesforce Object Query Language) allows developers to query records stored in the Salesforce database. In our current scenario we are going to write a subquery to fetch related records of an account in a single query. For example:
SELECT Id, Name, (SELECT Id, FirstName, LastName FROM Contacts) FROM Account WHERE Id = :accountId
This query fetches the Account record along with its related Contacts. As you can see we have used a sub-query inside a query. You can use this in Apex or other tools to retrieve related data.

Anatomy of a subquery in SOQL

Note: A subquery is a nested query inside a query.

To learn more about SOQL read this official Salesforce Documentation here.
Querying Related Contacts Using Apex
Apex is the most common approach for querying related records in Salesforce. You can write a SOQL query to fetch related Contacts and expose the data to your Lightning Web Component.
Apex Example Code
public with sharing class AccountContactController {
@AuraEnabled(cacheable=true)
public static List<Contact> getRelatedContacts(Id accountId) {
return [
SELECT Id, FirstName, LastName, Email
FROM Contact
WHERE AccountId = :accountId
];
}
}
Explanation:
- The
@AuraEnabled
annotation makes this method available to Lightning components. - The method queries all Contacts related to the given
accountId
.
LWC Integration with Apex
Below is an example of how to call this Apex method in LWC:
import { LightningElement, api, wire } from 'lwc';
import getRelatedContacts from '@salesforce/apex/AccountContactController.getRelatedContacts';
export default class RelatedContacts extends LightningElement {
@api recordId; // Holds the Account Id
contacts;
error;
@wire(getRelatedContacts, { accountId: '$recordId' })
wiredContacts({ error, data }) {
if (data) {
this.contacts = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.contacts = undefined;
}
}
}
Key Points:
- Use
@wire
to call the Apex method and bind the results to the component. - Handle both data and error scenarios.
Querying Related Contacts Using JavaScript in LWC
The Lightning framework also provides JavaScript-based methods for querying Salesforce data. Let’s explore two approaches: Wire Adapters and Imperative Apex Calls.
Wire Adapters for Fetching Contacts
The getRelatedListInfo
adapter can be used to fetch related lists programmatically. However, for custom queries, the Apex approach is often preferred.
import { LightningElement, api, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';
const FIELDS = [
'Account.Name',
'Account.Contacts'
];
export default class RelatedContactsWireAdapter extends LightningElement {
@api recordId;
account;
error;
@wire(getRecord, { recordId: '$recordId', fields: FIELDS })
wiredAccount({ error, data }) {
if (data) {
this.account = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.account = undefined;
}
}
}
Imperative Apex Calls in LWC
For scenarios requiring user interaction, you can use imperative Apex calls. Here is an example:
import { LightningElement, api } from 'lwc';
import getRelatedContacts from '@salesforce/apex/AccountContactController.getRelatedContacts';
export default class RelatedContactsImperative extends LightningElement {
@api recordId;
contacts;
error;
handleFetchContacts() {
getRelatedContacts({ accountId: this.recordId })
.then((result) => {
this.contacts = result;
this.error = undefined;
})
.catch((error) => {
this.error = error;
this.contacts = undefined;
});
}
}
Key Points:
- Use
getRelatedContacts
Apex method imperatively when you need to fetch data based on user actions (e.g., button clicks). - Always handle promise rejections with
.catch()
.
Best Practices for Querying Related Data in Salesforce
- Use SOQL Efficiently: Avoid querying unnecessary fields or records.
- Leverage Cacheable Methods: Use
@AuraEnabled(cacheable=true)
for read-only operations to improve performance. - Error Handling: Always handle errors gracefully in both Apex and LWC.
- Optimize Data Display: Use pagination or lazy loading for large datasets.
- Security Considerations: Enforce sharing rules with
with sharing
and validate user permissions.
By combining these techniques, Salesforce developers can build powerful, efficient, and user-friendly components to query and display related Contacts for Accounts in LWC. Don’t forget to test your implementation and include error-handling mechanisms for a seamless user experience.
Have questions or need clarification? Feel free to share your thoughts in the comments below!