0

I'm trying to retrieve the boolean value for the property from my controller. This value is being assigned after the call to the web service like this:

public Static Boolean myVariable { get; set; }

@future(callout=true)
public static void init()
{
    if (myMethod(123))
    {
        myVariable = true;
    }
}

In my page I need to retrieve what is the value for the property. For this I'm having there the action function which calls the method above:

<apex:actionFunction name="action" action="{!init}" rerender="pnl">

<apex:outputPanel id="pnl" layout="block">
    <script>
        var scb;
    
        function resolve() {
            return new Promise(resolve => {
                scb = '{!myVariable }';
            });
        }

        async function asyncCall() {
            result = await resolve();
            console.log('boolean value' + scb);
        }

        asyncCall();
    </script>
</apex:outputPanel>

But, this still doesn't work and I'm getting the endless "promise status pending". But, when I debugged my Apex code with debug logs, it works as expected. So, I', thinking that the problem is in my JS part. Can you help to make the correct call to the Apex part to get the value in the Visualforce page?

1
  • 1
    My gut feeling here is that @future doesn't really work with JS promises. This other, similar question would seem to confirm that. Is there any particular reason why you need that static method to be @future? Removing the annotation, or making it a helper method that you can call (indirectly) via the @future method and still be able to call it synchronously (well, not explicitly async) via JS remoting may be the way to go. Continuations are something else to consider.
    – Derek F
    Sep 20 '20 at 13:15
1

There are 2 problems in your code:

  1. Future apex method implementation and how it responds to the JS code.
  2. Incorrect promise implementation in JS.

To fix the point # 1, you should definitely consider the comment made by @DerekF.

You are running to 'promise status pending' indefinitely because of point # 2. A JS promise will always be in one of the following states: pending, fulfilled or rejected.

[pending: initial state, neither fulfilled nor rejected; fulfilled: meaning that the operation was completed successfully; rejected: meaning that the operation failed].

In your code, you are returning a JS promise that is never resolved. so, it continues to remain in pending state. This problem will persist even you fix the apex code (future or web service call). async/await internally works as a promise implementation and so, you don't need an explicit promise implementation. The following code will work (if the apex call is implemented correctly):

var scb;    
function resolve() {
    scb = '{!myVariable }';
}
async function asyncCall() {
    result = await resolve();
    console.log('boolean value' + scb);
}
asyncCall();

If you decide to implement promise, it should be as shown in snippet below.

var scb;    
function resolve() {
    return new Promise(resolve => {
        scb = '{!myVariable }';
        resolve(scb);
    });
}
async function asyncCall() {
    result = await resolve();
    console.log('boolean value' + scb); // result will have the same value as scb
}
asyncCall();

Don't expect the resolve(scb) in the above code snippet (or the entire previous snippet) to take care of proper execution and completion of the apex future call because this code will execute regardless indicating that the promise has been successful and change the promise state from pending to fulfilled state. The point I'm trying to make here is about how to resolve the promise (without getting into the details of apex execution).

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.