0

I have a static method named ABC in apex which is called multiple times from aura due to iteration

So in ABC i have few methods which need to be called only once in the first iteration.

How can prevent this inner methods from executing multiple times?

I tried with various approach but not working

4
  • I recommend you edit your question to make it clearer what you are trying to do, including adding some code or screenshots to illustrate what you have done so far. – Phil W Mar 4 at 14:39
  • 3
    From my reading in this, you need to make sure you pass the iteration count from Aura to the Apex and have the Apex only perform the other methods when that count is 0. – Phil W Mar 4 at 14:41
  • YeaYou got it correct. I started with that. But feeling weird. Is it a bad approach. – NBR Mar 4 at 15:13
  • Whether this is a good or bad approach depends on the processing you are doing. @StephenSS's approach is good for modest numbers of items and little specific processing for each, especially when you bulkify all the processing. If that doesn't fit for you, use the index approach. Remember, however, that in-memory state set up in one call from Aura is not visible to other calls from Aura. – Phil W Mar 4 at 16:12
1

Rather than iterating in aura and making a single request for each iteration, it may be possible to refactor in order to make a single request in aura passing the iterable thing to a refactored ABC that takes the matching type of iterable, then in ABC you can make decisions based on whether or not this is the first iteration.

Clarification: Instead of this pattern:

items.forEach( ( item ) => helper.updateOnServer( item ) );

...

ABC( Item__c item ) {
   // call some methods
}

You should try to refactor so that you can do something like this:

helper.updateOnServer( items );

...

ABC( List<Item__c> items ) {
    Boolean firstPass = true;
    for ( Item__c item : items ) {
        if ( firstPass ) {
            // do some things once
            firstPass = false;
        }
        // do some other things all the time
    }
}
6
  • Can u make it more clear? I am sending the request to apex for every iteration – NBR Mar 4 at 15:04
  • OK. I've added some fake code to try and help illustrate what I mean. – Stephen SS Mar 4 at 15:13
  • Will this approach make any kind of performance improvement do u think – NBR Mar 4 at 15:15
  • It really depends on the actual code that is running on both ends but, in general, the fewer round trips to the server and back, the better. There may also be considerations within a refactored ABC (things like query limits and so on) that you run into due to looping on the server. It's very hard to say if this will suit you, but if it does then it's worth a try to solve the issue. – Stephen SS Mar 4 at 15:20
  • 1
    Looks like a good approach to me. Note, however, this only works if you are not spending too much CPU time (or other per-transaction governor limits) in processing each entry in the list and the list isn't too big. The benefit of doing separate requests from Aura, where the client "orchestrates" the processing is that you have full limits for each request from the Aura component for each item. – Phil W Mar 4 at 16:09
1

You might consider creating an @AuraEnabled method that calls the methods you only want to run once, and execute that first from LWC. Then you can exclude the one-off apex methods entirely from the iterated calls. You add an additional server call, yes, but with the benefit of greater code simplicity, maintainability, and elegance. Any performance degradation should be unnoticeable.

Example (your method ABC is runOnEachIteration here for clarity):

CHANGE

// LWC:
for (const item of items) {
    await runOnEachIteration();
}

// APEX:
@AuraEnabled
public static void runOnEachIteration() {
    if (/* try to figure out if it hasn't been run yet */) {
        doThisOnce();
        doThatOnce();
    }
    
    doThisForEach();
}

INTO

// LWC:
if (items.length > 0) {
    await runOnce();
    for (const item of items) {
        await runOnEachIteration();
    }
}

// APEX:
@AuraEnabled
public static void runOnce() {
    doThisOnce();
    doThatOnce();
}

@AuraEnabled
public static void runOnEachIteration() {
    doThisForEach();
}
0

This is called as Recursion.

In order to handle the recursive calls, we can use static boolean variable(s) and check its values, that is, you can use static Boolean variable with default value true and in the trigger/desired logic, before executing your code you can keep a check that the variable is true or not. Once you check make the variable as false, that will avoid the logic from being called again.

SF basic article to handle Recursion.

Another SF article that stresses best practices to avoid recursion.

4
  • But on the next transaction it is again initialized to default value right? – NBR Mar 4 at 14:11
  • Be aware that both references point to articles that actually describe the use of an invalid means to block recursion in triggers. See this previous Q&A or any one of a bunch of others for explanation as to why this is an anti-pattern. – Phil W Mar 4 at 14:12
  • But I am not at all referencing to trigger – NBR Mar 4 at 14:14
  • Is it possible to get the old value in apex? – NBR Mar 4 at 14:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.