JavaScript SelectRows wait for end request

LabKey Support Forum (Inactive)
JavaScript SelectRows wait for end request nicyon  2014-05-06 02:11
Status: Closed
 
Hello,

I am currently working with the labkey javascript API, and am facing some problems. From what I understood from the labkey documentation, the requests are asynchronous, meaning that if a function calls, for instance a LABKEY.Query.selectRows, it won't wait the query is finished to exit the function.

So my question is, how can I make sure it waits the query is finished ?

Thank you very much in advance, hoping I have been clear enough

[EDIT]

So I think I may have found a problem to the solution, by using a multi request. The only problem, is when I try to execute my code, it tells me : "uncaught exception: You must specify a schemaName!". I dont't understand what I am doing wrong, since I have followed the documentation. This is how I created a config :

var config={
    schemaName : "study",
    queryName : "qName",
    containerPath : "container",
    requiredVersion: '13.2',
    success : function onSuccess(data){
                [...]
    },
    failure : function onFailure(err){
        alert(err.exception);
    }
};

And I simply build a new multi request as shown in the documentation :

var multiR = new LABKEY.MultiRequest();

and added

multiR.add(LABKEY.Query.selectRows, config);

What am I doing wrong ?

Thanks again in advance for all your help

[/EDIT]
 
 
jeckels responded:  2014-05-06 09:03
Asynchronous means that you don't get the results from the server immediately as the result of calling LABKEY.Query.selectRows(). Instead, at some point in the future, your success or failure callbacks will be invoked, when the browser gets the response back from the server. When the callback function is invoked, though, it will have the full response from the server. This isn't unique to LabKey's JavaScript API, this is how AJAX works in JavaScript to make requests a web server.

This might be a bit clearer with a simple modification to the example usage in the API docs:

https://www.labkey.org/download/clientapi_docs/javascript-api/symbols/LABKEY.Query.html#.selectRows

<script type="text/javascript">
    function onFailure(errorInfo, options, responseObj)
    {
        if (errorInfo && errorInfo.exception)
            alert("Failure: " + errorInfo.exception);
        else
            alert("Failure: " + responseObj.statusText);
    }

    function onSuccess(data)
    {
        alert("Success! " + data.rowCount + " rows returned.");
    }

    LABKEY.Query.selectRows({
            schemaName: 'lists',
            queryName: 'People',
            columns: ['Name', 'Age'],
            success: onSuccess,
            failure: onFailure
        });
        alert("Immediately after invoking selectRows()");
</script>

In this case, you'll see that the first popup you get is one that says "Immediately after invoking selectRows()". Then, at some point in the future, you'll get a second popup with the success or failure message.

I hope this helps.

Thanks,
Josh
 
nicyon responded:  2014-05-06 10:43
Hello,


Thank you very much for your response. But I'm afraid I'm more interested, to quote your example, in having the alert message(failure or success) before the "Immediately after invoking selectRows()".

In other words, is there a way to wait for the function onSuccess to be finished before continuing to the next instruction, which is alert("Immediately after invoking selectRows()") in your example.

Thank you very much again in advance for any help
 
jeckels responded:  2014-05-06 10:48
I'm sorry to say that's not possible, due to JavaScript's basic programming model when it comes to requesting data from web servers.

However, this is usually easy enough to accommodate in your code. Instead of putting the code right after the call to selectRows(), move it inside of your success callback function. JavaScript closures make it simpler to get the scoping to work. For example:

    var someValue = 'Test value';
    LABKEY.Query.selectRows({
            schemaName: 'lists',
            queryName: 'People',
            columns: ['Name', 'Age'],
            success: function (data)
            {
                 alert("Success! " + data.rowCount + " rows returned and value is " + someValue);
            },
            failure: onFailure
        });

Thanks,
Josh
 
nicyon responded:  2014-05-06 11:27
Hello,

Thank you very much for your enlightenment. I will now be able to continue, and solve my current problem.


Thank you very much again for you precious help
 
martin responded:  2014-11-28 02:57
hi,

my code:
---------------------------
var availableQueries = [];

function populateAvailableQueries()
{
  LABKEY.Query.getQueries({
   schemaName: 'lists',
   success: function(queriesInfo)
    {
     for (var j = 0; queriesInfo.queries.length; j++)
     {
      availableQueries.push(queriesInfo.queries[j].name);
     }
    }
   });

//here i cannot use availableQueries[] because it shows empty
}

from what i understood, there is no way then to assure the result of these api functions will be available right after execution...is that true?

what is the correct way to use the output so that it is fully available after execution?

thanks
Martin
 
jeckels responded:  2014-11-28 12:22
Hi Martin,

Yes, that's correct. The browser will send a request to the server, and when it gets the response at some point in the future, it will call your success function. This isn't specific to LabKey's JavaScript API - this is the standard pattern for how JavaScript code in web browsers makes calls to web servers.

The typical usage pattern is to use the success function to do whatever you need with availableQueries. In most cases, it's straightforward to simply put your code, say, right after your for loop inside the same function, instead of putting it outside of the callback function.

If you're not familiar with callbacks in JavaScript, this might give some useful background:

http://recurial.com/programming/understanding-callback-functions-in-javascript/

Thanks,
Josh
 
martin responded:  2014-11-29 05:38
[EDITED]

hi,
thank you very much, your advise to put operations with result inside the success function works fine:)

martin