web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics CRM (Archived)

Synchronous vs Asynchronous when using Web-API on web-resource

(0) ShareShare
ReportReport
Posted on by

When using the new Web-API for on-premise 2016 , the documentation I have seen indicates to make the call asynchronous for the XMLHTTPRequest.

However, making it asynchronous seems to not work in getting expected results back on time. 

For example I am initializing a variable to equal a return value that comes from an asynchronous web-api call.  The variable becomes undefined. However, setting a breakpoint in the web-api call itself, the expected value is returned. It appears that between the line declaring the variable and iterations of checking the readystate and status, the javascript continues on before the web-api request is truly finished.  This makes sense being asynchronous but it results in bad data.  If I make the call synchronous without a check on readystate and status the data expected returns and populates the variable as expected.

This has happened on other web-api calls that we are putting together.  Any ideas ?  Would prefer to use asynchronous as that is the recommendation but it does not seem to work as expected.

*This post is locked for comments

I have the same question (0)
  • Goutham A Profile Picture
    2 on at

    Hi R T,

    Web Api is asynchronous by default.

    I could not clearing understand what you are assigninging to a a variable. can you please paste some sample code to get better picture.

  • gdas Profile Picture
    50,091 Moderator on at

    If I my understanding is correct when you set async  true that means the line of code where you send request to API  will execute  then very immediately next line of codes will execute , no matter about your rest call finished or not and set the value in the readystate or not. If you assign any value in the readystate then return the value  from that point only using call back method.

    Now if you set async false which means at the point you are sending the api request, the next line of code will not execute until and unless your API request is finished and set the value in readystate.

    If you debug the code both set async true/false then I believe you will understand.

  • Aric Levin - MVP Profile Picture
    30,190 Moderator on at

    Hi R T,

    If you need the code to execute immediately, and not continue with execution of next statement, you will need to set the async parameter to false. If your code can run asynchronously, and you don't need the values for your execution, then you can set async to true.

    Hope this helps.

  • Community Member Profile Picture
    on at

    Thanks - that makes sense. Typically for us we are using it to retrieve information and based on that hide or disable fields on a form.  Sometimes the value retrieved is used immediately , as in the next line, sometimes it is later.  I was under the impression that it should be using async and thus want to be sure correct norms are followed.

  • Suggested answer
    Shidin Haridas Profile Picture
    3,497 on at

    In addition, if you want to use async methods, you would need to implement Promises.

    And some 3rd party library such as BlueBirdPromise library.

    Having async methods on load is preferred,as it helps with form loading.

  • Community Member Profile Picture
    on at

    Does using callbacks help in a situation where a call to get some data takes a while but I need the value on the next line of code?

    Trying to understand the advantage in the case where I need the information before I can evaluate a condition.  The sdk says to use it async so I would like to do that.  

    Example scenario below-  If using xmlhttprequest in async mode using a callback will that prevent the conditional statement from being evaluated until the data has been retrieved ?  

    Var FirstName = GetUserFirstName(UserID);

    if (Firstname == "Fred") {

    do something // disable a field, etc .

    }

    Function GetUserFirstName (UserID) {

    /// xmlhttprequest in async mode here

    return json data  - firstname

    }

  • Suggested answer
    gdas Profile Picture
    50,091 Moderator on at

    Hi R T,

    Considering your code async mode how it will run -

    Step 1:

    Execution Start Here - time 12:01 PM

     Function GetUserFirstName (UserID) {

    Step 3: 

    Execution Start Here - time 12:03 PM  [Due to asynchronous mode you can not received the first name here]

    if (Firstname == "Fred") {

    do something // disable a field, etc .

    }

    Step 2:

    Execution Start Here - time 12:02 PM

    /// xmlhttprequest in async mode here

    Step 4:

    Received First Name - time 12:05 PM

    return json data - firstname

    }

    So to handle this you should call your function inside onreadystatechange or onload of the XMLHttpRequest async call.

    Step 1:

    Execution Start Here - time 12:01 PM

    Function GetUserFirstName (UserID) {

    Step 2:

    Execution Start Here - time 12:02 PM

     call xmlhttprequest in async mode here

    Step 3:

    Received First Name - time 12:05 PM

    json data - firstname

    You should write the call back inside the method when you get the result.

    Step 4: 

    Execution Start Here - time 12:06 PM  [Due to asynchronous mode need to write call back logic after received the result]

    if (Firstname == "Fred") {

    do something // disable a field, etc .

    }

    In Summary here is the detail code will be look like - 

    GetFirstName();
    
    function GetFirstName() {
        var resstatus;
        var id = Xrm.Page.data.entity.getId();
        var getIDD = id.substr(1, id.length - 2);
        var req = new XMLHttpRequest();
        req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/contacts?$filter=contactid eq (" + getIDD + ")", true);
        req.setRequestHeader("OData-MaxVersion", "4.0");
        req.setRequestHeader("OData-Version", "4.0");
        req.setRequestHeader("Accept", "application/json");
        req.setRequestHeader("Content-Type", "application/json;charset-utf-8");
        req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
        req.send();
        req.onreadystatechange = function () {
            if (this.readyState === 4) {
                req.onreadystatechange = null;
                if (this.status === 200) {
                    var result = JSON.parse(this.response);
                    var firstName = result["firstname"];
                    callbacToSetFirstName(firstName);
                }
            }
            else {
            }
        };
        return resstatus;
    }
    
    function callbacToSetFirstName(firstName)
    {
    
        Xrm.Page.getAttribute('new_name').setValue(firstName);
    }


    Hope this helps.

  • Community Member Profile Picture
    on at

    Thanks,

    mimicking what you've done I can see the callback function getting called with the data I'm expecting. But does that mean within the callback function I still cannot use a return statement to send the data to the original variable which was calling the web-api function ?

    In other words:

    var myData = SomeWebAPIFunctionCall(ID)

    SomeWebAPIFunctionCall (ID)

    /// create async xmlhttp request object like above with a call back function

    callback (fieldValue)

    // call back function

    function callback (data) {

    return data;

    }

    Will the myData variable still remain undefined ?

  • Community Member Profile Picture
    on at

    querying synchronously does the trick well but concerned it's not the right way as everywhere I see in the documentation it indicates to go asynch. Yet in many cases I cannot wait for the value to come back at a later time.

  • Suggested answer
    Shidin Haridas Profile Picture
    3,497 on at

    RT, it depends on the scenario you are working with.

    For example, changing the account lookup should bring in values from the account lookup.

    Such onchange and onsave events should be all sync calls.

    Form load calls can be async, as by the time the form loads, the call would be executed.

    And while loading your own custom web-resources, custom grids etc, suggested to have async calls.

    But a proper algorithm and proper design of code can ensure that you dont have too many calls going out.

    Like, scenarios where you need to check for the user's security roles, you can maybe use advantage of the browser cache to store those values.

    So that the numbers of data calls being done to retrieve security roles and check is lesser.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics CRM (Archived)

#1
SA-08121319-0 Profile Picture

SA-08121319-0 4

#1
Calum MacFarlane Profile Picture

Calum MacFarlane 4

#3
Alex Fun Wei Jie Profile Picture

Alex Fun Wei Jie 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans