views:

216

answers:

2

Hi,

Using a form in a dialog box I am using Dojo in jsp to save the form in my database. After that request is completed using dojo.xhrPost() I am sending in another request to update a dropdown box that should include the added form object that was just saved, but for some reason the request to update the dropdown is executed before saving the form in the database even though the form save is called first. Using Firebug I can see that the getLocations() request is completed before the sendForm() request. This is the code:

<button type="button" id="submitAddTeamButton" dojoType="dijit.form.Button">Add Team
                    <script type="dojo/method" event="onClick" args="evt">

                        sendForm("ajaxResult1", "addTeamForm");
                        dijit.byId("addTeamDialog").hide();
                        getLocations("locationsTeam");
                    </script>

function sendForm(target, form){
    var targetNode =  dojo.byId(target);

    var xhrArgs = {
        form: form,
        url: "ajax",
        handleAs: "text",
        load: function(data) {

            targetNode.innerHTML = data;
        },
        error: function(error) {
            targetNode.innerHTML = "An unexpected error occurred: " + error;
        }

    }

    //Call the asynchronous xhrGet
    var deferred = dojo.xhrPost(xhrArgs);
}

function getLocations(id) {
    var targetNode =  dojo.byId(id);

    var xhrArgs = {
        url: "ajax",
        handleAs: "text",
        content: {
            location: "yes"
        },
        load: function(data) {

            targetNode.innerHTML = data;
        },
        error: function(error) {
            targetNode.innerHTML = "An unexpected error occurred: " + error;
        }
    }

    //Call the asynchronous xhrGet
    var deferred = dojo.xhrGet(xhrArgs);
}

Why is this happening? Is there way to make the first request complete first before the second executes?

To reduce the possibilities of why this is happening I tried setting the cache property in xhrGet to false but the result is still the same.

Please help!

+3  A: 

The first A in Ajax stands for "asynchronous", which means things occur "at their own pace": most likely the requests are sent in the order you expect, but they complete the other way around simply because the second one is faster. Yes, of course you can wait to even start (send) the second request until the first one completes -- most simply, you can just put the starting of the second request in the callback function of the first.

Alex Martelli
I can't put the second request in the callback function of the first because the second one is used in other parts of the website where the first one is not.Is there a way to control in what order the responses are handled?
mm2887
@mm2887, you could do what you want -- delay the 2nd function if the 1st is running and hasn't been answered yet -- but it's messy and all, if you could change your architecture it would be SO much better. Anyway, e.g.: have a global boolean flag normally true. Code sets it to false just before sending 1st ajax call and back to true when that response arrive. 2nd call checks the flag, if false, it loops sleeping for 100 milliseconds or so each time until it becomes true.
Alex Martelli
Thanks for the idea, but it seems messy like you said so I instead combined the two requests into one.
mm2887
+3  A: 

As Alex said, asynchronous requests are just that - their order is not guaranteed. If you want to guarantee their order, you can make them synchronous if you like. There is an option sync: true I think that you can send with the request args. This causes the browser to freeze up until the request gets back, so it's not recommended unless you have no other option, and the request is very quick.

You can also submit whatever data you need along with the data of the current request. For example, suppose dropdown A's value determines the list choices available in dropdown B. Rather than submitting a change when dropdown A is changed, then refreshing dropdown B's choices, what you can do is submit A's value at the time when dropdown B is opened, and process it in the server logic that determine's B's choices. (This assumes you have a drop-down widget with choices generated by the server, rather than a standard tag.)

RMorrisey
great idea! This worked and simplified my code.I am now sending it in as one request and having the response be the updated drop down list with the added object.
mm2887