Understanding Wire vs Imperative Apex Method Calls in Salesforce Lightning Web Components (LWC)

Understanding Wire vs Imperative Apex Method Calls in Salesforce Lightning Web Components (LWC)

Introduction:

Salesforce Lightning Web Components (LWC) provides two ways to call Apex methods – wire and imperative. It’s crucial to understand the differences between Wire vs Imperative Apex Method Calls in LWC. Both wire and imperative methods in Salesforce LWC are used to retrieve and manipulate data from the server side.

This blog post will help you understand Wire vs Imperative Calls in LWC. It will explain the differences between the wire and imperative calls. Additionally, it will cover their pros and cons and practical use cases for each.

Contact Us For SFDC Admin, Apex and LWC Trainings or any support at – cozmosoft2018@gmail.com
Learn Salesforce Flows From Basic to Advance With Our Udemy Course, along with using LWC and Aura in Flows

Section 1: Understanding Wire and Imperative Calls

In Salesforce LWC, Apex methods can be called using two different methods – wire and imperative. Understanding the differences between these two methods is essential for building efficient and effective LWCs.

a) Definition of wire and imperative calls in LWC:
  • Wire adapters / service in LWC provide a declarative way to access Salesforce data and Apex methods. They leverage a reactive programming model, automatically fetching and updating data when input parameters or component context (like recordId) change. This approach simplifies data retrieval. It reduces the need for manual coding. It also ensures seamless synchronization between the user interface and the underlying Salesforce data. SFDC Documentation for Wire.
  • Imperative method calls in LWC provide developers with explicit control over when and how Salesforce Apex methods are executed. Unlike wire adapters, which are reactive and automatic, imperative calls are triggered programmatically. These are typically in response to user interactions, such as button clicks. This approach is ideal for executing actions based on dynamic conditions. It supports complex business logic. It also provides precise error-handling mechanisms using JavaScript promises.
b) How Wire and Imperative calls work in LWC:

Wire calls dynamically fetch data based on changes to context parameters, such as user selections. In a component where opportunities are filtered by stage, the wire adapter retrieves updated data automatically. This happens whenever the selected stage is changed. This ensures the UI stays in sync with the latest data.

For Example – This LWC retrieves opportunities. They are filtered by a dynamically selected stage name from a dropdown. It uses the “fetchData” Apex method. The wire adapter automatically updates the data whenever the selected stage is changed by user from stage dropdown on ui.

import { LightningElement, wire } from 'lwc';
import fetchData from '@salesforce/apex/MyController.fetchOpportunities';

export default class ExampleComponent extends LightningElement {
    selectedStage = 'Closed Won'; // Default stage filter
    opportunities; // Stores retrieved opportunities

    // Wire adapter fetches opportunities based on the selected stage
    @wire(fetchData, { stageName: '$selectedStage' })
    wiredOpportunities({ data, error }) {
        if (data) {
			// Assign retrieved opportunities
            this.opportunities = data;
        } else if (error) {
			
        }
    }

    // Handler for dropdown value change
    handleStageChange(event) {
		// Update the stage filter
        this.selectedStage = event.target.value;
    }
}

Imperative calls provide explicit control over data fetching, allowing developers to determine when and how the Apex method is executed. For example, in a component, opportunities are fetched based on the user-selected stage. The imperative call is triggered when the component loads. This occurs during the connectedCallback. It is also triggered each time the user updates the stage from the dropdown. This approach offers greater flexibility and control. It is ideal for handling user-driven actions and more complex business logic, compared to the wire adapter.

For Example – This LWC uses the fetchData Apex method. It retrieves opportunities filtered by a stage chosen from a dropdown menu. It fetches the data during component initialization and updates it manually whenever the user selects a new stage. Unlike wire calls, the developer explicitly controls the data retrieval process, ensuring complete flexibility in execution and error handling.

import { LightningElement } from 'lwc';
import fetchData from '@salesforce/apex/MyController.fetchOpportunities';

export default class ExampleComponent extends LightningElement {
	// Default stage filter
    selectedStage = 'Closed Won';
	// Stores retrieved opportunities
    opportunities;

    // Fetch opportunities when the component is connected
    connectedCallback() {
        this.fetchOpportunityData();
    }

    // Method to fetch opportunities using imperative call
    fetchOpportunityData() {
        fetchData({ stageName: this.selectedStage })
            .then((result) => {
				// Assign retrieved opportunities
                this.opportunities = result;
            })
            .catch((error) => {
				
            });
    }

    // Handler for dropdown value change
    handleStageChange(event) {
		// Update the stage filter
        this.selectedStage = event.target.value;
		// Fetch updated opportunities
        this.fetchOpportunityData();
    }
}
c) Differences between the wire and imperative calls:

AspectWire CallsImperative Calls
Data Retrieval
Automatically retrieves data when tracked properties or context parameters change.Explicitly invoked by the developer when needed (e.g., on button click, page load, etc.).
Automatic UpdatesAutomatically updates when the tracked property changes, keeping the component in sync with the server.No automatic updates. Data must be manually updated when needed by the developer.
Data StorageStores data in a reactive variable, which updates automatically when the tracked property changes.Stores data in a regular variable, and the developer must manually update it after fetching new data.
Server-side Data SyncData is fetched and updated only when the tracked property or context parameter changes.Data is fetched explicitly by the developer, based on when the developer chooses to trigger the call.
Control Over ExecutionExecution is automatic based on property changes; less control over timing.Full control over when and how data is fetched, allowing for more precise timing and custom logic.
DML OperationsCannot handle DML operations like insert, update, or delete in apex method.Suitable for DML operations in Apex Method, as it offers full control over when and how these operations are performed.
Error HandlingError handling is automatic and managed by the wire service. Errors are returned through the wire result.Requires manual error handling and custom logic to handle exceptions and responses.
Unsupported ObjectsCannot be used with objects not supported by the User Interface API, such as Task and Event.Can handle objects not supported by the User Interface API, including Task and Event.
DebuggingMight be challenging to debug in complex scenariosMore flexible for debugging, as the developer has control over the entire flow and can add custom logs.
d) Pros and cons of using wire and imperative calls:
  • Pros of using wired apex method call:
    1. Automatic data refreshing: Wired apex method calls provide automatic data refreshing. This means that any changes made to the data are automatically reflected in the UI. It does not require any additional code.
    2. No need for custom error handling. The wired apex method calls handle errors automatically. You don’t need to write any additional code for error handling.
    3. Better performance: Wired apex method calls use a reactive programming model. They optimize the data transfer between the server and client. This results in better performance.
  • Cons of using wired apex method call:
    1. Limited data manipulation: Wired apex method calls are read-only and do not allow for any data manipulation or updates.
    2. Limited control over the data: Wired apex method calls automatically fetch data. They also cache data, which can result in less control over the data and its behavior.
    3. Limited support for complex queries: Wired apex method calls only support simple queries. They may not be suitable for more complex queries that require additional logic.
  • Pros of using imperative apex method call:
    1. Full control over data: Imperative apex method calls provide full control over data and its behavior. These calls allow for DML operations such as updates, inserts, and deletes as needed.
    2. Support for complex queries: Imperative apex method calls enable the execution of complex queries. They allow for additional logic, making them suitable for more complex use cases.
    3. Better debugging: The imperative apex method calls provide more control over the data. They also allow for easier debugging of issues.
  • Cons of using imperative apex method call:
    1. More error-prone: Imperative apex method calls require more error handling code. They do not handle errors automatically as wired apex method calls.
    2. Manual data refreshing: Imperative apex method calls do not provide automatic data refreshing. You need to write additional code to manually refresh the data.
    3. Lower performance: Imperative apex method calls require more code and data transfer between the server and client. This situation results in potentially lower performance compared to wired apex method calls.

Section 2: Using Wire and Imperative Calls in Apex Method Calls

a) Importing Apex Methods in LWC

To import an Apex method for use in LWC, we should use the default import syntax in JavaScript via the @salesforce/apex scoped packages, as shown below:

import apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodReference';
  • apexMethodName—A symbol that identifies the Apex method.
  • apexMethodReference—The name of the Apex method to import.
  • Classname—The name of the Apex class.
  • Namespace—If the class is in the same namespace as the component, don’t specify a namespace. If the class is in a managed package, specify the namespace of the managed package.
b) How to use wire and imperative calls in Apex method calls in LWC

Apex methods are used in Salesforce to perform complex computations, data manipulation, and DML operations. Lightning Web Components (LWC) allow developers to invoke Apex methods using either the wire service or imperative calls. In this section, we will explore how to use wire and imperative calls in Apex method calls in LWC.

To call an Apex method, a Lightning web component can:

1. Wire a property:

Developers often wire an Apex method as a property for simple use cases without extra logic. It’s shorter and easier to read, ideal for small components without much customization. However, it may not be suitable for more complex use cases that require additional logic or error handling.

If you decorate a property with @wire, it returns the results to the property’s data or error property.

Syntax –

import apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodReference';

@wire(apexMethod, { apexMethodParams }) propertyName;

Example –

  • This Lightning Web Components (LWC) retrieves contact records. These are related to a specific Account record. It displays them in a table format.
  • It uses a wire service to fetch data from the server-side Apex controller method named getContacts in the ContactController class.
  • By using “$” in the parameter of the wire property, we make it reactive. If the value of the parameter “recordId” changes, the wire will call the apex method again automatically. It retrieves and updates the data.

apexWireProperty.html

<template>
    <lightning-card
        title="ApexWirePropertyExample "
        icon-name="custom:custom63">
        <div
            class="slds-text-heading_small slds-text-align_left"
            style="padding-left: 15px">
            Get Contacts of An Account
        </div>
        <div class="slds-var-m-around_medium">
            <template lwc:if={hasContacts}>
                <table
                    class="slds-table slds-table_bordered slds-table_cell-buffer">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Email</th>
                            <th>Phone</th>
                        </tr>
                    </thead>
                    <tbody>
                        <template for:each={contacts.data} for:item="contact">
                            <tr key={contact.Id}>
                                <td>{contact.Name}</td>
                                <td>{contact.Email}</td>
                                <td>{contact.Phone}</td>
                            </tr>
                        </template>
                    </tbody>
                </table>
            </template>
            <template lwc:elseif={contacts.error}>
                {contacts.error.body.message}
            </template>
            <template lwc:else> No matching Data Found.... </template>
        </div>
    </lightning-card>
</template>

apexWireProperty.js

// Import the LightningElement class , the wire and the api decorator from the lwc module
import { LightningElement, wire, api } from 'lwc';
// Import the getContacts method from the ContactController Apex class
import fetchData from '@salesforce/apex/ContactController.getContacts';
// Declare the ApexWireProperty class as the default export
export default class ApexWireProperty extends LightningElement {
    @api recordId; //the record id of account
    //using the @wire decorator to connect to the getOpportunities Apex method
    // and assinging the result in contacts list
    @wire(fetchData,{accId: '$recordId'}) contacts;
    /**
     * hasContacts method is used to return boolean true or false, 
       if contacts properties has data or not.
     * @return boolean true or false
     */
    get hasContacts() {
        return this.contacts && this.contacts.data && this.contacts.data.length > 0;
    }
}

apexWireProperty.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>56.0</apiVersion>
     <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
        <target>lightningCommunity__Page</target>
        <target>lightningCommunity__Default</target>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>

ContactController.cls

/*
 * This class is used as an controller class for apexWireProperty LWC.
 */
public with sharing class ContactController {
    /**************************************************************************************
    * @Description : The getContacts returns a list of contact objects,
    *                based on the record id of account.
    * @Param	   : acc - record id of account 
    * @Return      : List<Contact> getContacts
    **************************************************************************************/
    @AuraEnabled(cacheable=true)
    public static List<Contact> getContacts(Id accId) {
        return [SELECT Id, Name, Email, Phone 
                FROM Contact WHERE AccountId=: accId 
                WITH SECURITY_ENFORCED 
                ORDER BY Name LIMIT 10];
    }
}
Demo ApexWirePropertyExample
2. Wire a function:

Wiring the apex method using the function, offers more control and customization over the wired function. It allows you to handle errors and manipulate data in a more fine-grained way.

If you decorate a function with @wire, it returns the results in an object. The object contains a data property or an error property.

Syntax –

import apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodReference';

@wire(apexMethod,{ apexMethodParams })
functionname({ error, data }) {
    if (data) {
        
    } else if (error) {
        
    }
}

Example –

  • This Lightning Web Components (LWC) retrieves matching opportunity records. It bases the retrieval on the user-entered opportunity stage and the amount. The records are then displayed in a table format.
  • It uses a wire service as a function. This function fetches data from the server-side Apex controller method. The method is named getOpportunities in the OpportunityController class.
  • The getOpportunities method returns the list of opportunities. This happens if the opportunity stage matches the searchStage. It also requires the amount to be greater than or equal to searchAmount.
  • By using “$” in the parameter of the wire function, we make it reactive. Any time the value of the parameter “recordId” changes, the wire automatically calls the apex method again. This update retrieves and refreshes the data.

apexWireMethodWithParams.html

<template>
    <lightning-card
        title="ApexWireMethodWithParamsExample "
        icon-name="custom:custom63">
        <div
            class="slds-text-heading_small slds-text-align_left"
            style="padding-left: 15px">
            Get Matching Opportunities with Stage Name and Amount
        </div>
        <div class="slds-var-m-around_medium">
            <lightning-combobox
                label="Opportunity Stage"
                options={stageOptions}
                onchange={handleStageChange}>
            </lightning-combobox>
            <lightning-input
                type="number"
                onchange={handleKeyChange}
                class="slds-var-m-bottom_small"
                label="Amount"
                placeholder="Enter Amount to Search Opps..."
                value={searchAmount}>
            </lightning-input>
            <template lwc:if={hasOpps}>
                <table
                    class="slds-table slds-table_bordered slds-table_cell-buffer">
                    <thead>
                        <tr>
                            <th>Opportunity Name</th>
                            <th>Opportunity Stage</th>
                            <th>Opportunity Amount</th>
                        </tr>
                    </thead>
                    <tbody>
                        <template
                            for:each={opportunities}
                            for:item="opportunity">
                            <tr key={opportunity.Id}>
                                <td>{opportunity.Name}</td>
                                <td>{opportunity.StageName}</td>
                                <td>{opportunity.Amount}</td>
                            </tr>
                        </template>
                    </tbody>
                </table>
            </template>
            <template lwc:elseif={error}>{error.body.message} </template>
            <template lwc:else> No matching Data Found.... </template>
        </div>
    </lightning-card>
</template>

apexWireMethodWithParams.js

// Import the LightningElement class and the wire decorator from the lwc module
import { LightningElement, wire } from "lwc";
// Import the getOpportunities method from the OpportunityController Apex class
import getOpportunities from "@salesforce/apex/OpportunityController.getOpportunities";
/** The delay used when debouncing event handlers before invoking Apex. */
const DELAY = 300;
// Declare the ApexWireMethodWithParams class as the default export
export default class ApexWireMethodWithParams extends LightningElement {
    // Defining class properties
    opportunities;
    error;
    searchAmount = "";
    searchStage;
    // Defining the stage options as an array of objects
    stageOptions = [
        { label: "---None---", value: "" },
        { label: "Prospecting", value: "Prospecting" },
        { label: "Qualification", value: "Qualification" },
        { label: "Value Proposition", value: "Value Proposition" },
        { label: "Closed Won", value: "Closed Won" },
        { label: "Closed Lost", value: "Closed Lost" }
    ];
    //using the @wire decorator to connect to the getOpportunities Apex method
    @wire(getOpportunities, { stage: "$searchStage", amount: "$searchAmount" })
    /**
     * wiredOpportunities method is used to handle the 
       data returned from the Apex method.
     * It assigns the data to the opportunities property.
     * It also assigns the error to error property in case of error.
     * @param {Object} data - data returned from the Apex method
     * @param {Object} error - error returned from the Apex method
     */
    wiredOpportunities({ error, data }) {
        if (data) {
            this.opportunities = data;
            this.error = undefined;
        } else if (error) {
            this.error = error;
            this.opportunities = undefined;
        }
    }
    /**
      * handleKeyChange method is used to handle the change of amount field
        and debouncing it to avoid a large number of Apex method calls.
      * It assigns the searchAmount property to user entered opportunity amount value.
      * @param {Object} event - event data
      */
    handleKeyChange(event) {
        // Debouncing this method: Do not update the reactive property as long as this function is
        // being called within a delay of DELAY. This is to avoid a very large number of Apex method calls.
        window.clearTimeout(this.delayTimeout);
        const searchAmount = event.target.value;
        // eslint-disable-next-line @lwc/lwc/no-async-operation
        this.delayTimeout = setTimeout(() => {
            this.searchAmount = searchAmount;
        }, DELAY);
    }
    /**
     * hasOpps method is used to return boolean true or false, 
       if opportunites properties has data or not.
     * @return boolean true or false
     */
    get hasOpps() {
        return this.opportunities && this.opportunities.length > 0;
    }
    /**
     * handleStageChange method is used to handle the change event of stage field.
     * It assigns the searchStage property to user selected opportunity stage value.
     * @param {Object} event - event data
     */
    handleStageChange(event) {
        this.searchStage = event.detail.value;
    }
}

apexWireMethodWithParams.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>56.0</apiVersion>
     <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
        <target>lightningCommunity__Page</target>
        <target>lightningCommunity__Default</target>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>

OpportunityController.cls

/*
 * This class is used as an controller class for apexWireMethodWithParams LWC.
 */
public with sharing class OpportunityController {
    /**************************************************************************************
    * @Description : The getOpportunities returns a list of Opportunity objects,
    *                based on the user selected stage and amount.
    * @Param	   : stage - user selected stage 
    * @Param	   : scope - user entered amount
    * @Return      : List<Opportunity> opportunities
    **************************************************************************************/
    @AuraEnabled(cacheable=true)
    public static List<Opportunity> getOpportunities(String stage, String amount) {
        List<Opportunity> opportunities = new List<Opportunity>();
        if(String.isNotEmpty(amount) && String.isNotEmpty(stage)){
            Integer amt = Integer.valueOf(amount);
            opportunities = [SELECT Id, Name, StageName, Amount, CloseDate 
                                    FROM Opportunity 
                                    WHERE StageName=: stage 
                                    AND Amount >= :amt 
                                    WITH SECURITY_ENFORCED];
        }        
        return opportunities;
    }
}

NOTE: The data property and the error property are hardcoded values in the API. You can only use these values.

Demo ApexWireMethodWithParamsExample
3. Call a method imperatively

Imperative calls to Apex methods are when you explicitly call a method and handle the returned results in your code. This approach gives you more control over the data retrieval and manipulation process.

Example –

  • This Lightning Web Components (LWC) retrieves matching opportunity records. It bases the retrieval on the user-entered opportunity stage and the amount.
  • These records are then displayed in a table format. It uses an imperative method call to fetch data. This data comes from the server-side Apex controller method named getOpportunities. The method is in the OpportunityController class.
  • The getOpportunities method returns the list of opportunities on page load. This is based on default searchStage and searchAmount. It also returns opportunities on-demand on the click of the Get Opportunities button. This happens when the opportunity stage matches the searchStage and the amount is greater than or equal to searchAmount.

apexImperativeMethodWithParams.html

<template>
    <lightning-card
        title="ApexImperativeMethodWithParams"
        icon-name="custom:custom63">
        <div
            class="slds-text-heading_small slds-text-align_left"
            style="padding-left: 15px">
            Get Matching Opportunities with Stage Name and Amount
        </div>
        <div class="slds-var-m-around_medium">
            <lightning-combobox
                label="Opportunity Stage"
                options={stageOptions}
                onchange={handleStageChange}
                value={searchStage}>
            </lightning-combobox>
            <lightning-input
                type="number"
                onchange={handleAmountChange}
                class="slds-var-m-bottom_small"
                label="Amount"
                placeholder="Enter Amount to Search Opps..."
                value={searchAmount}>
            </lightning-input>
            <template lwc:if={hasOpps}>
                <table
                    class="slds-table slds-table_bordered slds-table_cell-buffer">
                    <thead>
                        <tr>
                            <th>Opportunity Name</th>
                            <th>Opportunity Stage</th>
                            <th>Opportunity Amount</th>
                        </tr>
                    </thead>
                    <tbody>
                        <template
                            for:each={opportunities}
                            for:item="opportunity">
                            <tr key={opportunity.Id}>
                                <td>{opportunity.Name}</td>
                                <td>{opportunity.StageName}</td>
                                <td>{opportunity.Amount}</td>
                            </tr>
                        </template>
                    </tbody>
                </table>
            </template>
            <template lwc:elseif={error}>{error.body.message} </template>
            <template lwc:else> No matching Data Found.... </template>
            <br />
            <lightning-button
                label="Get Opportunities"
                variant="brand"
                onclick={fetchData}>
            </lightning-button>
        </div>
    </lightning-card>
</template>

apexImperativeMethodWithParams.js

// Import the LightningElement class and the wire decorator from the lwc module
import { LightningElement } from "lwc";
import getOpportunities from "@salesforce/apex/OpportunityController.getOpportunities";

export default class ApexImperativeMethodWithApexImperativeMethodWithParamsComplexParams extends LightningElement {
  // Defining class properties
  opportunities;
  error;
  searchAmount = "2500"; //set default search amount
  searchStage = "Prospecting"; //set default search amount
  // Defining the stage options as an array of objects
  stageOptions = [
    { label: "---None---", value: "" },
    { label: "Prospecting", value: "Prospecting" },
    { label: "Qualification", value: "Qualification" },
    { label: "Value Proposition", value: "Value Proposition" },
    { label: "Closed Won", value: "Closed Won" },
    { label: "Closed Lost", value: "Closed Lost" }
  ];
  /**
    * connectedCallback method is used to get the matching
      opportunity data on page load for searchAmount = "2500"
      and searchStage = 'Prospecting'
    */
  connectedCallback() {
    this.fetchData();
  }

  /**
   * handleAmountChange method is used to handle the change of amount field
   * It assigns the searchAmount property to user entered opportunity amount value.
   * @param {Object} event - event data
   */
  handleAmountChange(event) {
    this.searchAmount = event.target.value;
  }
  /**
   * handleStageChange method is used to handle the change event of stage field.
   * It assigns the searchStage property to user selected opportunity stage value.
   * @param {Object} event - event data
   */
  handleStageChange(event) {
    this.searchStage = event.detail.value;
  }
  /**
   * fetchData method is used to handle the data returned from the getOpportunities Apex method.
   * It convert the searchStage & searchStage to an parameterObject
     and shows us an example of passing multiple params to apex
   * It assigns the data to the opportunities property.
   * It also assigns the error to error property in case of error.
   * @param {Object} event - event data
   */
  fetchData() {
    // Creating the object that represents the shape
    // of the Apex wrapper class.
    let parameterObject = {
      someString: this.searchStage,
      someInteger: this.searchAmount
    };    
    /* Calling the imperative Apex method with the JSON
    object as parameter.*/
    getOpportunities({ wrapper: parameterObject })
      .then((result) => {
        this.opportunities = result;
        this.error = undefined;
      })
      .catch((error) => {
        this.opportunities = undefined;
        this.error = error;
      });
  }
  /**
   * get hasOpps method checks whether the opportunities property is not undefined
   * and has at least one opportunity.
   * @returns {boolean} - true if opportunities exist, false otherwise
   */
  get hasOpps() {
    return this.opportunities && this.opportunities.length > 0;
  }
}

apexImperativeMethodWithParams.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>56.0</apiVersion>
     <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
        <target>lightningCommunity__Page</target>
        <target>lightningCommunity__Default</target>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>

OpportunityController.cls

/*
 * This class is used as an controller class for apexImperativeMethodWithParams LWC.
 */
public with sharing class OpportunityController {
    /**************************************************************************************
    * @Description : The getOpportunities returns a list of Opportunity objects,
    *                based on the user selected stage and amount.
    * @Param	   : CustomWrapper - wrapper object
    * @Return      : List<Opportunity> opportunities
    **************************************************************************************/
    @AuraEnabled
    public static List<Opportunity> getOpportunities(CustomWrapper wrapper) {
        List<Opportunity> opportunities = new List<Opportunity>();
        if(String.isNotEmpty(wrapper.someString) && String.isNotEmpty(wrapper.someInteger)){
            Integer amt = Integer.valueOf(wrapper.someInteger);
            opportunities = [SELECT Id, Name, StageName, Amount, CloseDate 
                                    FROM Opportunity 
                                    WHERE StageName=: wrapper.someString 
                                    AND Amount >= :amt
                                    WITH SECURITY_ENFORCED];
        }        
        return opportunities;
    }
    /**
     * Wrapper class used to demonstrate how we can pass complex paramters from LWC.
     * Note that inner classes are not supported when exchanging with LWC.
     */
    public with sharing class CustomWrapper {
        @AuraEnabled
        public string someInteger { get; set; }
        @AuraEnabled
        public String someString { get; set; }
    }
}
Demo ApexImperativeMethodWithParams

Refer to the LWC Recipes git hub repo for more Wire and Imperative Call examples.

For more helpful articles please visit – https://thesalesforcedev.wordpress.com/

Leave a comment