Log in

View Full Version : @InvocableMethod Annotation



cathlilly
12-03-2024, 03:30 PM
I’m using the @InvocableMethod annotation in my Apex class to allow a Flow to update accounts, but I’m encountering an issue when trying to pass multiple input parameters. Salesforce is throwing an error saying, “Methods defined with @InvocableMethod must have a single parameter of type List.” How can I structure my method to accept multiple parameters, such as account names and industries, while adhering to the @InvocableMethod constraints? Here’s the code I’m working with during my Salesforce training in India (https://www.crsinfosolutions.com/salesforce-training-india/), which isn’t functioning as expected:

public with sharing class AccountUpdater {
@InvocableMethod
public static void updateAccounts(String accountName, String accountIndustry) { // Error: Multiple parameters not allowed
List<Account> accountsToUpdate = [SELECT Id FROM Account WHERE Name = :accountName];
for (Account acc : accountsToUpdate) {
acc.Industry = accountIndustry;
}
update accountsToUpdate;
}
}

How can I modify this code to meet the requirements of the @InvocableMethod annotation?

Indraja
12-05-2024, 07:46 PM
To resolve the issue and adhere to the constraints of the @InvocableMethod annotation, which requires a single parameter of type List, you need to encapsulate the input parameters (accountName and accountIndustry) into a custom class. This custom class can then be passed as a single List parameter to the updateAccounts method.

Here’s how you can modify your code:

Solution: Use a Wrapper Class for Input Parameters



public with sharing class AccountUpdater {
// Wrapper class to encapsulate input parameters
public class AccountUpdateRequest {
@InvocableVariable(required = true)
public String accountName; // Name of the Account
@InvocableVariable(required = true)
public String accountIndustry; // New Industry for the Account
}

@InvocableMethod
public static void updateAccounts(List<AccountUpdateRequest> requests) {
// Collect account names from the requests
Map<String, String> nameToIndustryMap = new Map<String, String>();
for (AccountUpdateRequest request : requests) {
nameToIndustryMap.put(request.accountName, request.accountIndustry);
}

// Query Accounts based on provided names
List<Account> accountsToUpdate = [SELECT Id, Name FROM Account WHERE Name IN :nameToIndustryMap.keySet()];

// Update the Industry field for the queried Accounts
for (Account acc : accountsToUpdate) {
acc.Industry = nameToIndustryMap.get(acc.Name);
}

// Perform the DML update
if (!accountsToUpdate.isEmpty()) {
update accountsToUpdate;
}
}
}



Explanation

1. Wrapper Class:

A public class AccountUpdateRequest is defined to hold the two input parameters (accountName and accountIndustry).

The @InvocableVariable annotation is used to make the variables accessible to Salesforce Flow or Process Builder.



2. Method Signature:

The updateAccounts method now accepts a single List parameter of type AccountUpdateRequest, satisfying the constraints of the @InvocableMethod annotation.



3. Processing the Input:

The method iterates through the list of requests, creating a mapping of account names to industries.

Accounts are queried based on the names provided in the requests.



4. Updating Accounts:

The industry of each account is updated based on the mapping, and then all updates are applied in a single DML statement.




How to Use in Flow

In the Flow, you can create a collection variable where each element is an instance of the AccountUpdateRequest class.

Pass this collection to the updateAccounts method.


This structure ensures that your method is compatible with the @InvocableMethod constraints while supporting multiple input parameters.