'Is setting interval right way to make sure Ajax call is completed?
I have two input text field and one save button.
<input type="text" id="myInput" />
<input type="text" id="searchResult"/>
<button id="myButton>save</button>
The myInput text field has onchange event which then sends Ajax request to get some data and show the result to searchResult text field.
The save button has click event which validate the input of searchResult text field for empty string and such. If ok then proceed with saving.
$("myInput").change(function() {
var userInput = $("myInput").val(); //get value from the text field
var responseText = callAjaxToGetData(userInput): //XHR request to get some data
$("searchResult").val( responseText ); //show the XHR result here
});
$("myButton").click(function() {
var searchResultField = $("searchResult").val(); //get value from the searchResult field
var isOK = validate(searchResultField); //check empty string and such
if(isOK) { saveDataViaAjax(userInput); }
});
Problem
When a user types in some text into the text field and then clicks on "save" button,
onchange eventis triggered,callAjaxToGetData()is called. (XHR)before
callAjaxToGetData()is completed and fill in thesearchResulttext field, myButtononclick eventis triggered.In side of
onclickevent handler, validation fails becausesearchResultfield is still empty.callAjaxToGetData()finally finishes and fill insearchResulttext field.
Ideally, callAjaxToGetData() is completed first then proceed with the process inside of onclick event so the validation won't fail.
This seems very common case people would face I guess so I'm wondering how you approach this problem?
I am thinking to put interval into onclick event like below (this requires responseText to be a global variable)
$("myButton").click(function() {
var interval = setInterval(function() { //call every 500ms
//if responseText is not null that means i know the ajax inside of onchange event is completed for sure.
if( responseText != null ) {
clearInterval(interval);
var searchResultField = $("searchResult").val(); //get value from the searchResult field
var isOK = validate(searchResultField); //check empty string and such
if(isOK) { saveDataViaAjax(userInput); }
}
}, 500);
});
Solution 1:[1]
Code below might not be exact but I'd disable the button before ajax and enable after callback returns.
$("myInput").change(function() {
$("myButton").attr("disabled", "disabled");
var userInput = $("myInput").val(); //get value from the text field
var responseText = callAjaxToGetData(userInput, function(data) {
$("searchResult").val( data); //show the XHR result here
$("myButton").removeAttr("disabled");
}):
});
Solution 2:[2]
I think in order to avoid onClick event process goes faster than ajax process in onChange event, setting timer solved the problem.
First I created helper function which checks active ajax connection and calls function that would be otherwise called in onClick event.
helper
function check_pending_process(callback) {
var interval = setInterval(function() {
if($.active > 0) {
//do nothing here
}
else {
//no ajax is running, call the function after 500 ms
clearInterval(interval);
setTimeout(function() { window[callback].call() }, 500);
}
}, 100);
}
caller
function processButtonClick() {
var searchResultField = $("searchResult").val(); //get value from the searchResult field
var isOK = validate(searchResultField); //check empty string and such
if(isOK) { saveDataViaAjax(userInput); }
}
$("#myButton").click(function() {
check_pending_process("processButtonClick");
});
The 500 ms judgement is based on how long the process of post-ajax in onchange event takes. In my case, post-ajax process inside of onchange event is just put response text into the text field so 500 ms is enough.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | DanielEli |
| Solution 2 | Meow |
