Difference Between @wire and Imperative Way of Calling Apex Class in LWC

Difference Between @wire and Imperative Way of Calling Apex Class in LWC
Chinmaya By Chinmaya
5 Min Read

Introduction

When working with Lightning Web Components (LWC), you often need to fetch or manipulate data from Salesforce.
Salesforce provides two main ways to call Apex methods: 

    1. @wire decorator
    2. imperative approach.

Both have their own use cases, advantages, and limitations. In this blog post, we’ll explore the differences between these two approaches, when to use each, and provide examples to help you understand them better.

What is @wire Decorator?

    • The @wire decorator is a declarative way to call Apex methods or use Lightning Data Service (LDS) in LWC.
    • It automatically fetches data when the component loads and reactively updates the component when the data changes.

Key Features of @wire:

    1. Automatic Data Fetching: Fetches data as soon as the component loads.

    2. Reactive Updates: Automatically updates the UI when the data changes.

    3. Error Handling: Provides a built-in mechanism to handle errors.

    4. Caching: Uses caching for better performance (especially with LDS).

What is Imperative Approach?

    • The imperative approach involves calling Apex methods on demand (e.g., when a button is clicked). It gives you more control over when and how data is fetched or actions are performed.
    • In case of Imperative approach, the apex method is not called automatically.

Key Features of Imperative Calls:

    1. Manual Control: You decide when to call the Apex method.

    2. On-Demand Fetching: Useful for actions like button clicks.

    3. Error Handling: Requires manual error handling using .catch()

Key Differences Between @wire and Imperative Apex

Aspect @wire (Reactive) Imperative

Execution Control

Automatically triggers based on parameters or lifecycle.
Manually invoked in response to user actions.

Syntax

Uses the @wire decorator.
Calls Apex methods like a JavaScript function.

Use Case

Ideal for automatically fetching data when components render or parameters update.
Best for user-driven actions like button clicks.

Error Handling

Errors are accessed via error property of the @wire.
Explicit handling with try-catch or .catch().

Data Refresh

Automatically refreshes when dependent parameters change.
Must be re-invoked manually to fetch updated data.

Dynamic Parameters

Supports reactivity based on parameter changes.
Requires dynamic parameters to be passed explicitly.

Flexibility

Limited flexibility; dependent on the @wire lifecycle.
High flexibility; executed whenever needed.

UI Blocking

Non-blocking (async).
Non-blocking (async).

Governor Limits

Automatically optimized.
Manually optimized by the developer.

When to Use @wire vs. Imperative Calls

Use @wire When:

    • You need to fetch data automatically when the component loads.

    • You want the UI to reactively update when the data changes.

    • You’re working with Lightning Data Service (LDS) for record data.

Use Imperative Calls When:

    • You need to fetch data on demand (e.g., on a button click).

    • You’re performing actions like saving or updating records.

    • You want more control over when and how data is fetched.

Practical Example 1: Fetching Data Automatically with @wire

This example demonstrates fetching a list of accounts when the component loads.

Apex Class:

				
					public with sharing class AccountController {
    @AuraEnabled(cacheable=true)
    public static List<Account> getAccounts() {
        return [SELECT Id, Name, Industry FROM Account LIMIT 10];
    }
}
				
			

JavaScript File

				
					import { LightningElement, wire } from 'lwc';
import getAccounts from '@salesforce/apex/AccountController.getAccounts';

export default class WireExample extends LightningElement {
    @wire(getAccounts)
    accounts;

    get hasAccounts() {
        return this.accounts?.data?.length > 0;
    }
}
				
			

HTML File

				
					<template>
    <template if:true={hasAccounts}>
        <ul>
            <template for:each={accounts.data} for:item="account">
                <li key={account.Id}>{account.Name} - {account.Industry}</li>
            </template>
        </ul>
    </template>
    <template if:true={accounts.error}>
        <p style="color:red;">Error: {accounts.error.message}</p>
    </template>
</template>
				
			

Practical Example 2: Fetching Data with Imperative Apex on Button Click

Apex Class:

				
					public with sharing class AccountController {
    @AuraEnabled
    public static List<Account> getAccounts() {
        return [SELECT Id, Name, Industry FROM Account LIMIT 10];
    }
}
				
			

LWC JavaScript:

				
					import { LightningElement, track } from 'lwc';
import getAccounts from '@salesforce/apex/AccountController.getAccounts';

export default class ImperativeExample extends LightningElement {
    @track accounts;
    @track error;

    fetchAccounts() {
        getAccounts()
            .then((result) => {
                this.accounts = result;
                this.error = undefined;
            })
            .catch((error) => {
                this.error = error.body.message;
                this.accounts = undefined;
            });
    }
}
				
			

LWC HTML

				
					<template>
    <lightning-button label="Fetch Accounts" onclick={fetchAccounts}></lightning-button>
    <template if:true={accounts}>
        <ul>
            <template for:each={accounts} for:item="account">
                <li key={account.Id}>{account.Name} - {account.Industry}</li>
            </template>
        </ul>
    </template>
    <template if:true={error}>
        <p style="color:red;">Error: {error}</p>
    </template>
</template>
				
			

If you’re eager to dive deeper into the @wire approach or the imperative method of calling Apex classes, explore the detailed post below:

Conclusion

    • @wire is ideal for automatic and reactive data fetching. Use it when you want to fetch data as soon as the component loads and keep the UI updated.

    • Imperative calls are perfect for on-demand actions like button clicks or saving records. Use them when you need more control over when and how data is fetched.

By understanding the differences and use cases for each approach, you can build more efficient and user-friendly Lightning Web Components! 🚀

Explore more Salesforce insights and best practices on Writtee. 🚀

Share This Article
Follow:
Chinmaya is working as a Senior Consultant with a deep expertise in Salesforce. Holding multiple Salesforce certifications, he is dedicated to designing and implementing cutting-edge CRM solutions. As the creator of Writtee.com, Chinmaya shares his knowledge on educational and technological topics, helping others excel in Salesforce and related domains.
Leave a comment