I need to fetch data from and external API. Since I have to make the call again and again to check the status until the status is TRUE, I have placed it in a recursive loop. I need to know what's wrong with my logic, because I'm unable to get the desired output. Does the response.status update itself or do i need to make another ajax like how I have done in the code
fetchFunct();
function fetchFunct(){
console.log("entered function");
$.ajax
({
type: "GET",
url: "/content/mosaic/multi/preview/status/"+testId ,
async: false,
dataType : "json",
success : function(response)
{
console.log(response);
if(response.status === false)
{
console.log("Processing details"); //show still in progress
$("#load").show();
$("#heading").hide();
$("#b1").hide();
$("#b2").hide();
$("#b3").hide();
$("#b4").hide();
$("#b5").hide();
}else
{
$("#load").hide();
console.log("Loading 1");
$("#b1").click(function(){
$("#ad22img").attr("src","http://" + response.images.android22);})
console.log("Loading 2");
$("#b2").click(function(){$("#ad4img").attr("src","http://" + response.images.android4);})
console.log("Loading 3");
$("#b3").click(function(){ $("#apm6img").attr("src","http://" + response.images.appmail6);})
console.log("Loading 4");
$("#b4").click(function(){ $("#blbimg").attr("src","http://" + response.images.blackberryhtml);})
console.log("Loading 5");
$("#b5").click(function(){$("#iphnimg").attr("src","http://" + response.images.iphone5s);})
is_loaded = true;
}
}
}).fail(function(data) { console.log("FAIL"); }).done(function(data) { console.log("coming out of ajax");
});
if(!is_loaded)
{
console.log("entered if");
delay=delay*2;
if(delay>60)
{delay=1;}
setTimeout(fetchFunct,delay*1000);
}
//console.log("if not entered");
}
You should call your function again inside the callback function.
if(response.status === false)
{
console.log("Processing details"); //show still in progress
$("#load").show();
$("#heading").hide();
$("#b1").hide();
$("#b2").hide();
$("#b3").hide();
$("#b4").hide();
$("#b5").hide();
//Try again
setTimeout(function(){
fetchFunct();
},1000);
}else
No need for any of the setTimeout logic beneath your AJAX call.
Related
I'm trying to stop an Ajax request when a user click a button. But even if I made use the .abort(); the ajax keep requesting each 2 seconds. Basically, a user wait for an input from the server. If the response is 2, then after 2 second an ajax request need to be call. If the response is 3, then is it good. the function is not called anymore.
I tried different solutions, .arbord(); changed the ajax completely...etc None of the solution worked out. I guess I'm missing some concept here.
////////////////////// index.php
.
<button id="cancel" onclick="CancelRequest()">Cancel</button>
.
<script>
function CheckStatus(){
var jqXHR = $.ajax({
url: "status.php",
async: true,
cache: false,
type: "POST",
data: {data: id},
success: function(response){
var response;
if (response == 2) {
alert(response);
setTimeout(CheckStatus, 2000); /// NEED TO SEND THE REQUEST AJAX REQUEST AGAIN, the response needs to be 3
} else if (response == 3) {
alert("good");
} else {
alert("error");
}
}
});
}
CheckStatus(); // start ajax automatically
}
//cancel request if the user press a button
function CancelRequest() {
jqXHR.abort();
}
</script>
///////////////////////////////////// status.php
$number = $_POST['id'];
.
.
.
.
$number = 2;
if ($number['status'] === 3) {
echo "good";
} elseif ($result['status'] == 2) {
echo "repeat again";
} else {
echo "error";
}
I expect that when I call jqXHR.abort(); the ajax should stop. However it keep going forever.
Declare the variable jqXHR outside of the CheckStatus() function
<script>
var jqXHR;
function CheckStatus(){
jqXHR = $.ajax({
url: "status.php",
async: true,
cache: false,
type: "POST",
data: {data: id},
success: function(response){
var response;
if (response == 2) {
alert(response);
setTimeout(CheckStatus, 2000); /// NEED TO SEND THE REQUEST AJAX REQUEST AGAIN, the response needs to be 3
} else if (response == 3) {
alert("good");
} else {
alert("error");
}
}
});
}
CheckStatus(); // start ajax automatically
}
//cancel request if the user press a button
function CancelRequest() {
jqXHR.abort();
}
I am triggering multiple AJAX requests in a loop. They run in parallel and it is not clear which one will respond first.
If the response is successful, I can identify the request by analyzing the response.
for (kk = 0; kk < $('#style').val().length; kk++){
$.ajax({
type: "POST",
url: "/single",
data: {style: [$('#style').val()[kk]]},
success: function (results) {
if (results.status == 'success'){
$('#results').find('div').each(function(){
if ($(this).attr('id') == results.style){
$(this).empty().append(results.payload)
}
});
}
else{
$('#results').find('div').each(function(){
if ($(this).attr('id') == results.style){
$(this).empty().append('<b>' + results.style + ':</b> ' + results.payload)
}
});
}
},
error: function (error) {
console.log(error);
}
});
}
However, once in a while, the request fails and an error is triggered.
For a proper error handling, I would like to know to which of the (previously triggered) requests the error belongs.
Is there a clean method how a specific AJAX request can be identified?
I would recommend to pass in a identifier via context to the AJAX call which you can use inside the success or error methods:
for (kk = 0; kk < $('#style').val().length; kk++){
$.ajax({
type: "POST",
url: "/single",
data: {style: [$('#style').val()[kk]]},
// data inside "context" will be available as part of "this" in the success/error case.
context: {
"kk": kk
},
success: function (results) {
if (results.status == 'success'){
console.log("Element " + this.kk + " finished successfully.");
$('#results').find('div').each(function(){
if ($(this).attr('id') == results.style){
$(this).empty().append(results.payload)
}
});
}
else{
$('#results').find('div').each(function(){
if ($(this).attr('id') == results.style){
$(this).empty().append('<b>' + results.style + ':</b> ' + results.payload)
}
});
}
},
error: function (error) {
console.log("Element " + this.kk + "failed.");
console.log(error);
}
});
}
More information regarding context can be found in the jQuery documentation.
Regarding your comment about checking how many calls failed / succeeded: here is a JsFiddle demonstrating how to keep track of the call statistics.
I've got a JS file that's automatically run through an HTML script. I want the console to print out "changing to true" before it prints out "starting toggle". The reason for this is because I want the function to call an API and change the toggle "checked" states before it loads. How do I do this?
$(document).ready(function(){
for (var i=0;i<Object.keys(obj).length;i++) {
var obj_name = Object.keys(obj)[i];
obj_id = "#"+obj_name;
$(obj_id).bootstrapToggle();
console.log("starting toggle")
}
})
$("#samplekey").ready(function() {
checkKey("#samplekey", power_toggles["samplekey"]);
})
function checkKey(obj_id, url1){
var http_verb = "GET";
$.ajax({
url: url1,
type: http_verb
}).done(function(data) {
if (data == 1234) {
$(obj_id).prop("checked", true);
console.log("changing to true")
}
else
{
$(obj_id).prop("checked", false);
}
}).fail(function(data,textStatus,errorThrown) {
alert(errorThrown);
});
}
You could made this change in your code:
$(document).ready(function() {
checkKey("#someUrl", "someUrl")
})
function checkKey(obj_id, url1) {
var http_verb = "GET";
$.ajax({
url: url1,
type: http_verb
}).done(function(data) {
for (var i = 0; i < Object.keys(obj).length; i++) {
var obj_name = Object.keys(obj)[i];
obj_id = "#" + obj_name;
$(obj_id).bootstrapToggle();
console.log("starting toggle")
}
if (data == 1234) {
$(obj_id).prop("checked", true);
console.log("changing to true")
} else {
$(obj_id).prop("checked", false);
}
}).fail(function(data, textStatus, errorThrown) {
alert(errorThrown);
});
}
$("#samplekey").ready(function() {
checkPOEPower("#samplekey", power_toggles["samplekey"]);
})
And remember that Javascript is Asynchronous, this means that the code never stops for external requests or others events.
You should make the ajax request sync. Add a property "async: false" in your codes
$.ajax({
url: url1,
type: http_verb,
async: false
}).done(function(data) {
if (data == 1234) {
$(obj_id).prop("checked", true);
console.log("changing to true")
}
else
{
$(obj_id).prop("checked", false);
}
}).fail(function(data,textStatus,errorThrown) {
alert(errorThrown);
});
I am loading ajax load
function ajaxPageFilter(filterDiv, filterLink, filterName, loaderDivId, loaderId) {
jQuery("#" + filterDiv).load(filterLink, {'filterName': filterName}, function(data) {
jQuery("img.lazy").lazyload({effect : "fadeIn"});
jQuery('#'+loaderDivId).remove();
jQuery('#'+loaderId).remove();
});
}
Is there a way to do error handling for ajax load, in case if it fails.
thanks
You can capture the status argument in your callback, and have a condition to check if there is an error.
jQuery("#" + filterDiv).load(filterLink, {'filterName': filterName}, function(data, status) {
if(status == "error"){
// do something
} else {
jQuery("img.lazy").lazyload({effect : "fadeIn"});
jQuery('#'+loaderDivId).remove();
jQuery('#'+loaderId).remove();
}
});
I got an if-else script:
$('#favitem').live('click', function () {
var fid = $(this).parent().attr('id');
if (isFav(fid)) {
alert("Do you want to remove from favorite?");
}
else {
alert("Add to favorite?");
}
});
calling the isFav script function:
function isFav(fid) {
$.ajax({
url: '/Stock/IsFav',
type: 'GET',
data: { id: fid },
success: function (result) { return result; }
});
}
which in turn calling my controller action:
public Boolean IsFav(int id)
{
var food = dbEntities.FOODs.Single(f => f.FoodID == id);
if (food.FavFlag == 1)
{
return true;
}
else
{
return false;
}
}
Everything seems works fine, I get a true from firebug, BUT i get the alert message from the else statement. The if statement just never being entered.
I cant get what is wrong here. Any idea?? Please help..
The ajax request in isFav is async and the isFav method will return before it is completed.
This is probably how I would solve it:
function isFav(fid, callback) {
$.ajax({
url: '/Stock/IsFav',
type: 'GET',
data: { id: fid },
success: function (result) { callback(result); }
});
}
$('#favitem').live('click', function () {
var fid = $(this).parent().attr('id');
isFav(fid,function(result){
if(result && result.toLowerCase() == "true"){
alert("Do you want to remove from favorite?");
} else {
alert("Add to favorite?");
}
});
});
You want to make sure that the code in the if-block is run after the ajax request is done. In this snippet this is solved by the callback method that is called when the ajax success function is executed.
You're not really returning true from within isFav function. Also ajax is asynchornous, so your code (if statement) actually continues to execute until ajax finishes, so at the moment of execution the result of isFav is undefined. So that's why else is being executed.
You're gonna need some remodeling.
function isFav(fid) {
$.ajax({
url: '/Stock/IsFav',
type: 'GET',
data: { id: fid },
success: function (result) {
if(result == 'favorite') alert("Do you want to remove from favorite?");
else alert("Add to favorite?");
}
});
}
$('#favitem').live('click', function () {
var fid = $(this).parent().attr('id');
isFav(fid);
});