Lightning Web Components (LWC)
1. What is an Indexed field? Why use it?
Answer :
Indexed fields are stored with an index in the database, making queries on those fields faster. Standard indexed fields: Id, Name, CreatedDate, SystemModstamp, OwnerId, External ID fields, fields marked as Unique. Custom fields can be indexed if marked as External ID or Unique. For large data volumes, querying non-indexed fields causes 'Non-selective query' errors. You can request Salesforce to add a custom index via a support case.
2. What are the Decorators in LWC?
Answer :
@api — makes a property or method public. Properties are reactive and can be set by parent components. Methods are callable by parent via template ref.
@track — makes private properties reactive — when the property changes, the component re-renders. In modern LWC (API version 39+), all private properties are reactive by default for primitives and top-level object/array reassignment. @track is needed for deep reactivity within nested objects/arrays.
@wire — wires a property or function to a wire adapter (Salesforce data service or Apex method). Automatically reactive — re-runs when parameters change. Data comes in {data, error} structure.
3. Lifecycle Hooks in LWC — explain each.
Answer :
constructor() — runs first when component is created. Cannot access DOM or child elements. Use for initializing properties. Call super() first. Do not fetch data here.
connectedCallback() — runs when component is inserted into the DOM. Use for: data fetching, event listener setup, initialization logic. Child components may not be rendered yet.
renderedCallback() — runs after every render (including re-renders). Use cautiously — avoid DML/data fetch here as it can cause infinite loops. Use a flag to run once: if(this.isRendered) return; this.isRendered = true;
disconnectedCallback() — runs when component is removed from the DOM. Use for cleanup: unsubscribe from events, clear timers.
errorCallback(error, stack) — catches errors from child components. Acts as error boundary.
4. Lifecycle order for Parent-Child components?
Answer :
Construction order (top-down): Parent constructor → Parent connectedCallback → Child constructor → Child connectedCallback → Child renderedCallback → Parent renderedCallback
So: connectedCallback fires top-down, renderedCallback fires bottom-up. A console.log in child renderedCallback fires before parent renderedCallback.
5. When is @wire called in lifecycle?
Answer :
Wire provisioning happens after connectedCallback and before renderedCallback. Wire is called when the component is connected to the DOM and runs again whenever its reactive parameters change (prefixed with $). It is NOT called manually — it is automatically managed by the framework.
6. Difference between @wire and Imperative Apex call?
Answer :
@wire: Declarative, automatic, reactive — re-runs when parameters change, caches results, cannot perform DML (cacheable=true methods only). Data available as {data, error} object.
Imperative: Called explicitly (e.g., on button click or in connectedCallback). Can call non-cacheable methods (DML allowed). Returns a Promise. More control over when the call happens.
// Wire example
@wire(getAccounts, { recordId: '$recordId' }) accounts;
// Imperative example
connectedCallback() {
getAccounts({ recordId: this.recordId }).then(result => { this.accounts = result; }).catch(error => { this.error = error; });
}
7. How to make an Imperative call reactive (re-run when params change)?
Answer :
Use getter/setter with @api or @track to detect changes, then call the Apex method inside the setter or use a watcher pattern:
_recordId;
@api get recordId() { return this._recordId; }
set recordId(value) { this._recordId = value; this.loadData(); }
loadData() { getAccounts({ recordId: this._recordId }).then(r => this.data = r); }
8. Parent to Child communication in LWC?
Answer :
(1) @api property: Parent sets a public property on child via HTML attribute. Child must mark it @api. Reactive — child re-renders when parent changes the value.
(2) @api method: Parent calls a child's public method using a template reference.
// Child: expose method
@api refresh() { this.loadData(); }
// Parent HTML: <c-child ref='childComp'></c-child>
// Parent JS: this.refs.childComp.refresh();
(3) lwc:ref (API 59+): Modern way to get reference to child elements.
9. Child to Parent communication in LWC?
Answer :
Custom Events: Child dispatches a CustomEvent, parent listens with an event handler.
// Child JS
this.dispatchEvent(new CustomEvent('accountselected', { detail: { id: this.accountId } }));
// Parent HTML
<c-child onaccountselected={handleAccountSelected}></c-child>
// Parent JS
handleAccountSelected(event) { this.selectedId = event.detail.id; }
10. Communication between unrelated components (not parent-child)?
Answer :
Lightning Message Service (LMS): Publish-subscribe pattern for components across the DOM.
// Publisher
import { publish, MessageContext } from 'lightning/messageService';
import MY_CHANNEL from '@salesforce/messageChannel/MyChannel__c';
@wire(MessageContext) messageContext;
publish(this.messageContext, MY_CHANNEL, { recordId: this.recordId });
// Subscriber
import { subscribe, MessageContext } from 'lightning/messageService';
connectedCallback() {
this.subscription = subscribe(this.messageContext, MY_CHANNEL, (msg) => { this.recordId = msg.recordId; });
}
disconnectedCallback() { unsubscribe(this.subscription); }
11. Grandparent to Grandchild (A → B → C) and reverse?
Answer :
A → C (down): Pass @api property from A to B, B passes it to C.
C → A (up): C fires custom event with bubbles:true, composed:true. B doesn't need to handle it. A listens on the child C tag. OR use LMS.
// In C (child):
this.dispatchEvent(new CustomEvent('notify', { detail: data, bubbles: true, composed: true }));
// In A (grandparent HTML):
<c-b onnotify={handleNotify}></c-b> // event bubbles up through B to A
12. What is Shadow DOM?
Answer :
Shadow DOM is a browser feature that encapsulates a component's DOM and CSS. In LWC, each component's template is rendered inside a shadow root, preventing styles from leaking in or out. Synthetic shadow (polyfill) was used historically; native shadow is the modern approach. This encapsulation means parent CSS cannot directly style child elements unless CSS custom properties (styling hooks) are used.
13. Event bubbles and composed — what do they do?
Answer :
bubbles: true — event propagates up the DOM tree (from child to parent).
composed: true — event crosses the shadow DOM boundary, allowing it to propagate across component boundaries.
Default values: both are false. For cross-component event propagation: set both to true.
14. What is LDS (Lightning Data Service)?
Answer :
LDS provides wire adapters to read, create, edit, and delete records without writing Apex. It handles caching, FLS, and sharing automatically. Key adapters:
getRecord — fetch a single record's fields
getRecordCreateDefaults — get defaults for creating a record
getRelatedListRecords — fetch related list records
createRecord, updateRecord, deleteRecord — from lightning/uiRecordApi
Advantage: Caches data in browser, auto-updates all components using the same record. Limitation: Cannot handle complex logic like triggers or multi-object operations.
15. What is refreshApex?
Answer :
refreshApex() re-fetches data for a @wire property by making a new server call, bypassing the cache. Used when you know data has changed (e.g., after a DML operation) and need to update the UI.
import { refreshApex } from '@salesforce/apex';
@wire(getAccounts) wiredAccounts;
handleSave() {
saveRecord({ ... }).then(() => refreshApex(this.wiredAccounts));
}
16. Can we do DML inside a @wire method?
Answer :
No — Apex methods annotated with @AuraEnabled(cacheable=true) (required for @wire) cannot perform DML. If DML is needed, use an imperative call to a non-cacheable method. The framework throws an error if cacheable=true and DML is attempted.
17. Why does @AuraEnabled(cacheable=true) not allow DML?
Answer :
When cacheable=true, Salesforce caches the result in the browser and local cache. If DML were allowed, the cached value could become stale — inconsistent with the actual database state. By preventing DML, Salesforce ensures data consistency between cached results and org data.
18. Best practices for LWC?
Answer :
Use @wire for read operations, imperative for writes and user-triggered actions
Unsubscribe from LMS in disconnectedCallback to prevent memory leaks
Use lazy loading for large datasets — pagination or infinite scroll
Avoid DML in renderedCallback — use a flag to prevent infinite loops
Use SLDS for styling consistency
Minimise @track usage — use @api for public, plain assignment for private
Use lightning-record-form, lightning-record-view-form for standard record operations
Handle errors gracefully — check both data and error from wire
Use lwc:if/lwc:elseif instead of deprecated if:true/if:false
19. Difference between lightning-record-form and lightning-record-edit-form?
Answer :
lightning-record-form: Auto-layout, handles view/edit/create modes automatically, uses page layout field order. Less customisable.
lightning-record-edit-form: Manual layout — you explicitly specify each field with lightning-input-field. More customisable — custom validation, custom submit handling, custom field arrangement. Use this when you need control over individual fields or custom logic on save.
20. How to get recordId in LWC on a record page?
Answer :
import { LightningElement, api } from 'lwc';
export default class MyComponent extends LightningElement {
@api recordId; // Automatically populated when placed on a record page
}
For a Quick Action (not a record page), the recordId may not be auto-populated — use CurrentPageReference from lightning/navigation or pass it explicitly via design attributes.
21. How to show Toast messages in LWC?
Answer :
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
this.dispatchEvent(new ShowToastEvent({ title: 'Success', message: 'Record saved!', variant: 'success' }));
Variants: success (green), error (red), warning (yellow), info (blue). You can also set 'sticky' mode to keep the toast until dismissed.
22. How to call a flow from LWC?
Answer :
// HTML
<lightning-flow flow-api-name='My_Flow' onstatuschange={handleStatusChange}></lightning-flow>
// Can pass input variables:
<lightning-flow flow-api-name='My_Flow' flow-input-variables={inputVars}></lightning-flow>
// JS - inputVars is array of {name, type, value}
get inputVars() { return [{ name: 'recordId', type: 'String', value: this.recordId }]; }
23. How to call LWC from a Quick Action?
Answer :
In the component's XML metadata file, set targets to include force:lightningQuickAction or force:lightningQuickActionWithoutHeader. Then create a Quick Action of type 'Lightning Component' in Object Manager pointing to your component.
24. How to call LWC inside a Flow?
Answer :
Add 'lightning__FlowScreen' as a target in the component's XML. The component must implement FlowNavigationNextAction and FlowNavigationFinishAction interfaces if it needs to control navigation. Add @api inputAttributes and outputAttributes as needed.
25. What is LWC OSS?
Answer :
LWC Open Source (OSS) is the open-source version of LWC that can run outside Salesforce — on Node.js, in static sites, or other platforms. It uses the same programming model but without Salesforce-specific features like wire adapters, @salesforce imports, or platform authentication.
26. What is the use of @track decorator in 2024/2025?
Answer :
In modern LWC (API v39+), primitive properties are automatically reactive without @track. However, @track is still needed for deep reactivity within nested objects or arrays — if you reassign a property of a nested object (not the object itself), the UI won't update unless @track is used on the parent object.
27. How to use static resources in LWC?
Answer :
import myResource from '@salesforce/resourceUrl/MyLibrary';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
connectedCallback() {
loadScript(this, myResource + '/lib/mylib.min.js').then(() => { /* use lib */ });
}
28. What are slots in LWC?
Answer :
Slots allow parent components to pass HTML content into child component templates. Unnamed slot: <slot></slot> — accepts any content. Named slot: <slot name='header'></slot> — accepts content with slot='header' attribute. Used to build reusable container components.
29. Difference between Constructor and connectedCallback?
Answer :
Constructor: Called when the component class is instantiated. DOM is not available — cannot access this.template. Primarily for property initialisation. Must call super().
connectedCallback: Called when component is inserted into the DOM. Template is accessible. Used for data fetching, setting up subscriptions, and initialisation that needs DOM access.
30. What is lwc:ref? What is lwc:spread?
Answer :
lwc:ref: Template reference — allows JS to get a direct reference to an element or child component. this.refs.myRef accesses the element.
lwc:spread: Spreads an object's properties as attributes on an element. Similar to JavaScript's spread operator for HTML attributes. Available in newer API versions.
31. How to check custom permissions in LWC?
Answer :
import hasMyPermission from '@salesforce/customPermission/My_Permission_Name';
// Then in HTML: <template lwc:if={hasMyPermission}>... </template>
32. How to call LWC from Aura and vice versa?
Answer :
LWC inside Aura: Simply use the LWC as a child component in Aura's markup: <c:myLwcComponent recordId='{!v.recordId}'>. Communication from LWC to Aura uses CustomEvents with bubbles:true, composed:true.
Aura inside LWC: Not directly supported. You would need LMS or URL-based navigation as intermediaries.
33. event.target.value vs event.detail — difference?
Answer :
event.target.value: Standard DOM property — the current value of the input element that fired the event. Used with native HTML inputs.
event.detail: LWC custom event property — data packaged by the component that dispatched the custom event. Used with CustomEvent.
34. Promises in LWC/JavaScript?
Answer :
A Promise represents an asynchronous operation's eventual result. States: pending, fulfilled, rejected.
// Basic promise chain
getAccounts({ recordId: this.recordId })
.then(result => { this.accounts = result; })
.catch(error => { this.error = error; })
.finally(() => { this.isLoading = false; });
// Promise.all — run multiple promises in parallel
Promise.all([getAccounts(p1), getContacts(p2)]).then(([accounts, contacts]) => { ... });
// Async/await (cleaner syntax)
async connectedCallback() {
try { this.data = await getAccounts({ recordId: this.recordId }); }
catch(e) { this.error = e; }
}
35. What is lazy loading in LWC?
Answer :
Lazy loading defers loading content until it's needed — typically used for large data sets. In LWC, implement it via: (1) Pagination — load records in pages; (2) lightning-datatable's enable-infinite-loading — load more records as user scrolls; (3) Dynamic imports (for component-level lazy loading). Prevents loading all 50,000 records at once.
💬 Community Chatter
Loading...🔐
Join the Community Discussion
Login to ask questions, share answers, and connect with other Salesforce professionals.