Hi,

I have been reading around trying to understand promise resolution for ES5 JS within OutSystems Mobile and I'm not sure what I am doing wrong. I have a JS function which contains multiple promises however none of them appear to resolve before the rest of my JavaScript and OutSystems logic executes. I have two output parameters that are assigned to local variables on a screen but because the promises are not resolved by that point both output and local variables are blank.

code cannot be shared, but it looks like this:

xxxxSDK.getItems().then(function (items) {
                console.log(JSON.stringify(items));
                $parameters.ItemResult = JSON.stringify(items);
                console.log("got items");
                $resolve();
});

Please could anyone advice on how it would be possible for all the JavaScript to be fully executed before the OutSystems logic continues to execute?

thanks for your time,

Adam

Hi Adam,

The $resolve() would ensure that the calling action is informed about succesful completion of your promise, so that makes me wonder if the xxxxSDK.getItems() is resolved at all?

https://success.outsystems.com/Documentation/11/Extensibility_and_Integration/JavaScript/Extend_Your_Mobile_App_Using_JavaScript/Defining_Asynchronous_JavaScript_Code

Regards,

Daniel

Hi Daniel,

Thanks for the reply.

So i tried another function which i needed and that worked for me, which is good progress. The difference between the two though was my original code piece above was sat inside a another promise, though i didn't think that would cause issue?

so more like this:

xxxxSDK.analyseInput(input).then(function () {
       xxxxSDK.getItems().then(function (items) {
                console.log(JSON.stringify(items));
                $parameters.ItemResult = JSON.stringify(items);
                console.log("got items");
                $resolve();
       });
       $resolve();
});

When i debug this through chrome i do eventually get the console.log outputs in the browser console, however by then the client action containing the script has long since completed.

Regards,

Adam

Hi Adam,

Looking at your code i could quickly understand why you nest the second promise in the first. It looks like doing several asynchronous operations in a row would lead to the classic callback hell pyramid.

It doesn't seem to use data returned from the promise. If that is the the case you could maybe chain the promises https://javascript.info/promise-chaining

also, $resolve() is used to steer when control is passed back to your client action. So maybe the inner promise should have a javascript resolve() not $resolve().

I would love to figure this out for you, unfortunately I don't have that much spare time.

Regards,

Daniel

Solution

Hi Daniel,

Thanks for the help in trying to solve my problem.

I tried using resolve() as apposed to $resolve() for the inner promises but found that didn't change the behavior. 

From testing i have found that, for my case at least, nested promises won't work for what i'm doing, but because they don't rely on returned data from a previous promise (as you pointed out) i can separate them.

So i split my promises into multiple javascript elements (each containing one promise) and then passed an object parameter containing SDK data between each element, allowing me to pick up where i left off using the previous state of the SDK. Not an ideal solution but it works and simplifies the readability of the code structure.

Regards,

Adam

Solution

Adam Rushby wrote:

Hi Daniel,

Thanks for the help in trying to solve my problem.

I tried using resolve() as apposed to $resolve() for the inner promises but found that didn't change the behavior. 

From testing i have found that, for my case at least, nested promises won't work for what i'm doing, but because they don't rely on returned data from a previous promise (as you pointed out) i can separate them.

So i split my promises into multiple javascript elements (each containing one promise) and then passed an object parameter containing SDK data between each element, allowing me to pick up where i left off using the previous state of the SDK. Not an ideal solution but it works and simplifies the readability of the code structure.

Regards,

Adam

That seems to be a nice solution for the problem.