84
Views
6
Comments
Solved
Promise Asynchronous Action Call : getting error .then() is not an function
Question
Application Type
Reactive

Hi All,

I want to call a server action asynchronously in Reactive Web App so I thought to use Promise in outsystems.

I have already referred Outsystem Aynchrouous Javascript call reference

Defining Asynchronous JavaScript Code - OutSystems 11 Documentation 

https://success.outsystems.com/documentation/11/integration_with_external_systems/javascript/defining_asynchronous_javascript_code/ 

 

I am pasting sample code, on button click calling Javascript, and below is code

Please check below code


When this javascript code gets called, I got a error in browser console

Could you please help here why I am not able to call function here.

2021-03-18 21-03-15
Benjith Sam
 
MVP
Solution

Hi Dorine,

I'll try to explain based on my understanding and observations:

Synchronous: only one operation can happen at a time i.e., A must finish before B starts.

1) By default, client actions operates synchronously.

2) Code executed using the JS element operates synchronously, but it respects asynchronous calls made within the same scope.

With the shared approach:

  • The client action CallAsyncActionOnClick will operate synchronously
  • Calling the AsyncAction explicitly in a asynchronous manner will cause each elements defined in the AsyncAction flow to run asynchronously. However, each JS elements defined in the AsyncAction flow will still run synchronously due to its execution nature.

I have attached a sample OML to demonstrate the points mentioned above.

CA - Client Action

JS Ele - JavaScript Element/node


By wrapping the SetTimeout, the async function call is placed into the callback queue. It will be pushed to the call stack and executed once all synchronous code in the global execution context has finished. That's what happened behind the scenes with the example you shared.

Console statements are synchronous calls that got executed first. Then the timer function gets clearance to run in the global execution context.





I hope this helps!


Kind regards,

Benjith Sam

AsyncDemo_Ben.oml
2021-03-18 21-03-15
Benjith Sam
 
MVP

Hi Vaibhav,

It seems that you have missed the implementation described in the shared documentation.

When one of "$resolve()" or "$reject()" predefined functions is used in a given JavaScript element, the client action the element belongs to will be considered asynchronous.

The generated code for an element that contains one of these two predefined functions is surrounded with the creation of a promise.

Solution: In your implementation, ensure that you have a JS element/node defined in the ShowHelloMsg client action flow that uses either the "$resolve()" or "$reject()" predefined functions. By doing this, the server calls such as executing server actions or refreshing aggregates and the client action call will be considered asynchronous.

Basic Implementation:

Demo app: AsycDemo

I hope this helps you!


Kind regards,

Benjith Sam

UserImage.jpg
Vaibhav Pandey

HI @Benjith Sam ,

Thank you for your quick response , but still my problem is not solved.

Please take a look again in the code and please let me know what is still incorrect,

I am using $resolve() and $reject() function now but still statement

$action.ShowHelloMsg().then(function(result) 

is throwing error " .then() is not an function " ,

do I need to add any spcific JS library from the dependency module

I'm calling JS from the reactive application



Here below is ShowHelloMsg() action where I'm just showing msg,



If possible can you please share your demo oml file where you implemented async call

2021-03-18 21-03-15
Benjith Sam
 
MVP

Hi @Vaibhav Pandey,

You are still missing the part where you define a JavaScript element in the ShowHelloMsg client action flow that uses either the "$resolve()" or "$reject()" predefined functions.

By doing this, server calls such as executing server actions or refreshing aggregates (defined in the ShowHelloMsg client action flow) and the ShowHelloMsg client action call will be considered asynchronous.

Refer to the attached oml.


Kind regards,

Benjith Sam

AsyncDemo_Ben.oml
2021-09-06 15-09-53
Dorine Boudry
 
MVP

Hi @Benjith Sam ,

I'm not getting this, if I hear 'asynchronous', then I expect the AsyncAction to start running, and the calling action to continue working and not wait for the AsyncAction to finish.  But that is not the case when I test your demo app.

I added a start and stop log to your caller code 

I changed the async action to take 10 seconds to finish, also doing a console.log every second

This is what comes out of testing, the calling code only finishes after the AsyncAction is done :

For comparisong : doing it the dirty way, by setting a timer of 0 milliseconds

And then, it does continue running without waiting for the AsyncAction to finish

Dorine

2021-03-18 21-03-15
Benjith Sam
 
MVP
Solution

Hi Dorine,

I'll try to explain based on my understanding and observations:

Synchronous: only one operation can happen at a time i.e., A must finish before B starts.

1) By default, client actions operates synchronously.

2) Code executed using the JS element operates synchronously, but it respects asynchronous calls made within the same scope.

With the shared approach:

  • The client action CallAsyncActionOnClick will operate synchronously
  • Calling the AsyncAction explicitly in a asynchronous manner will cause each elements defined in the AsyncAction flow to run asynchronously. However, each JS elements defined in the AsyncAction flow will still run synchronously due to its execution nature.

I have attached a sample OML to demonstrate the points mentioned above.

CA - Client Action

JS Ele - JavaScript Element/node


By wrapping the SetTimeout, the async function call is placed into the callback queue. It will be pushed to the call stack and executed once all synchronous code in the global execution context has finished. That's what happened behind the scenes with the example you shared.

Console statements are synchronous calls that got executed first. Then the timer function gets clearance to run in the global execution context.





I hope this helps!


Kind regards,

Benjith Sam

AsyncDemo_Ben.oml
UserImage.jpg
Vaibhav Pandey

@Benjith Sam @Dorine Boudry 

Thanks you for your response, the error which I was getting while doing asynchronous call , is solved.

I used @Benjith Sam javascript code and that worked perfectly fine for me.

I am really glad and appreciate both of yours efforts.

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.