Reputation: 2699
The title of this question is not very clear but I cannot explain what I am asking without providing some code.
I am making a page which submits reports (which are arrays) using AJAX. I have functions stored in a library which submit the array to the PHP page that look like this:
function saveReport(params)
{
var url="reports/save.php";
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
{
return false;
}
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("POST",url,true);
//Send the proper header information along with the request
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.setRequestHeader("Content-length", params.length);
xmlHttp.setRequestHeader("Connection", "close");
xmlHttp.send(params);
}
function stateChanged()
{
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
{
if (xmlHttp.responseText == 'complete')
{
return true;
}
else
{
return false;
}
}
}
(I don't believe the GetXmlHttpObject() function is relevant to the question)
I would like to be able to call the saveReport() from my page like this
success = saveReport(params);
if (success == true)
{
alert('success');
}
else
{
alert('failure');
}
So the function saveReport() needs to return a value which is returned from the function stateChanged() when it is called so that the page that called saveReport() can then decide what to do - which may be a different on different pages. Is there any way of doing this?
I realise that it may be impossible the way I am trying but is there something I can do to the same effect.
Upvotes: 2
Views: 233
Reputation: 621
Looks like you have a couple problems here:
1) Async operations cause trouble with function returns, since the function will finish firing before the async response comes back.
2) A function will only return what you tell it to, so to get a function to return the result of another function, you'd need to do something like this: return stateChanged( args )
The solution to 1) is to use a callback, like so:
function saveReport( params, callback ){
...
xmlHttp.onreadystatechange = function(){
stateChanged( callback );
};
Run the callback inside stateChanged()...
function stateChanged( callback ){
...
callback( true );
...
callback( false );
Then pass the callback like so:
saveReport( params, function( boolean ){
if( boolean )
alert('success');
else
alert('failure');
};
Upvotes: 1
Reputation: 10974
You won't be able to do it like that because the request doesn't block (it's asynchronous). What you'll have to do is use a callback the same way you have your stateChanged()
set as the callback function for xmlHttp.onreadystatechange
.
You can make a new function that handles the results and call that from the stateChanged()
, passing true
or false
as its parameter to indicate success.
function stateChanged()
{
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
{
saveReportFinished(xmlHttp.responseText == 'complete');
}
else{
saveReportFinished(false);
}
}
function saveReportFinished(success) {
if (success == true)
{
alert('success');
}
else
{
alert('failure');
}
}
Technically you could just combine all of this into stateChanged()
, but I think it's cleaner this way.
Upvotes: 1
Reputation: 3309
Have you tried
success = saveReport(stateChanged());
if (success == true) {
alert('success');
} else {
alert('failure');
}
Upvotes: 0
Reputation: 8044
Is there a reason why you're rolling your own Ajax helper?
In this situation you're going to need a callback function to be fired when the server has responded so that you can do something with the response, whether it be a success or fail.
Obviously, you can use something like jQuery.ajax but that might be overkill for something this simple.
You could try one of the many micro Ajax libraries at http://microjs.com/#ajax to achieve what you're after.
Upvotes: 1