How to get multiple ajax request with promises - javascript

I'm trying to get a single image from each ajax request and append it to a li box container, the first ajax returns a list of 20 objects, with name and a url
$.ajax({
url: "http://pokeapi.co/api/v2/pokemon/",
dataType: "json",
method: "GET",
cache: false,
success: function(data) {
for (var i = 0; i<data.results.length ;i++){
$("#root ul").append('<li class="box"></li>');
$("li").eq(i).append('<h2>' + data.results[i].name +'</h2>');
}
setPkmImage(data.results);
console.log(data);
},
error: function(data) {
console.log("Error");
}
});
The problem starts when I try to make a call for each of those objects to request an image, it works with the async: false, but i don't want to do it that way since it takes a lot of time to load all the images.
function setPkmImage(res){
for (var i = 0; i < res.length; i++) {
var promise = $.ajax({
url: res[i].url,
dataType: "json",
method: "GET",
cache: false,
//async: false,
promise.done( function(data) {
console.log(data);
$("#root ul");
$("li").eq(i).append('<img src="' + data.sprites.front_default+ '"/>');
});
promise.fail( function(data) {
console.log("Error");
});
});
}
}
I'm trying to use promises but I don't know exactly how to structure it

Two major problems, one is syntax and the other is you need a closure loop
First the $.ajax is not closed properly.
Should look more like:
var promise = $.ajax({
url: res[i].url,
dataType: "json",
method: "GET",
cache: false
});
promise.done(...
promise.fail(...
As for the closure loop, i won't be what you want it to be inside the ajax callbacks because the for loop will have been completed before the data for requests is returned. Thus i will be at it's maximum by then
Try changing the for loop to $.each which creates a closure
$.each(res, function(i, item){
var promise = $.ajax({
url: item.url,
dataType: "json",
method: "GET",
cache: false
});
promise.done(...
promise.fail(...
})

I usually use the next solution. After first request is done, I've insert to dom img with url (url is come from request) and browser will load images automatically.

Related

How can I check if there are changes in my database

What I want is a technique to refresh my div if there are changes in my database. Here is the point,
What i want: How can i condition to know if the first value from my database is lesser than the upcomming value.
In my situation, i put my ajax function to be run every 5secs here is it:
lastcountQueue is declared as global in javascript
function check_getqueue() {
$.ajax({
url: siteurl+"sec_myclinic/checkingUpdates/"+clinicID+"/"+userID,
type: "POST",
dataType: "JSON",
success: function(data) {
lastcountQueue = data[0]['count'];
}
});
}
Q:where would i put the condition something if lastcountQueue < data[0]['count]; condition means something if the data is lesser than lastcountQueue it means there was a change in my database portion.
Another Clear Situation for my question:
I want to make a function like these: the ajax will run every 5 seconds where it query a value to count my no. of queues in database. If my first query is giving me 5 value, and the second is giving me again another 5, then there must be nothing change happens, then if my third value gives me 4, where it is not equal to the last query, then i would do something
Probably something like this:
function check_getqueue() {
$.ajax({
url: siteurl+"sec_myclinic/checkingUpdates/"+clinicID+"/"+userID,
type: "POST",
dataType: "JSON",
success: function(data) {
var tmpCountQ = data[0]['count'];
if (tmpCountQ < lastcountQueue) {
// Process the change
}
lastcountQueue = tmpCountQ;
}
});
}
Here is the updated answer:
function check_getqueue() {
$.ajax({
url: siteurl + "sec_myclinic/checkingUpdates/" + clinicID + "/" + userID,
type: "POST",
dataType: "JSON",
success: function(data) {
if (data[0]['count'] != lastcountQueue) {
//Your logic here
lastcountQueue = data[0]['count'];
}
}
});
}

JQuery UI Autocomplete sometimes doesn't show all the results

I am using JQuery UI for autocompletion where I take input and ping a server with that input and end create an array to be given to the source of autocomplete. Right now it works perfect sometimes, but when i print the people array sometimes not all the source data shows up on the screen that is shown in console.
let input =$("<input type='text'/>")
.appendTo('#dynamic-form-elements');
input.autocomplete({
source: [] // Initially empty
}).on('input', function () {
$.ajax({
url: "https://lookmeup/json/person/" + input.val(),
dataType: "json",
success: function (parsed_json) {
let people = [];
let results = parsed_json.data;
for (i = 0; i < results.length; i++) {
people.push(results[i][1])
}
console.log(people)
input.autocomplete('option', 'source', people);
}
});
})
You need to include the "minLength:" attribute in the autocomplete so it waits til you hit the minimum length before it performs the ajax.
You can see this in use here:
https://jqueryui.com/autocomplete/#remote-jsonp
The final code should look like this:
input.autocomplete({
source: function(req, response) {
$.ajax({
url: "https://lookmeup/json/person/" + req.term,
dataType: "json",
success: function (parsed_json) {
// do the stuff here and call response callback
}
});
},
minlength: 3
})
You should do this, use source as function: https://jqueryui.com/autocomplete/#remote
input.autocomplete({
source: function(req, response) {
$.ajax({
url: "https://lookmeup/json/person/" + req.term,
dataType: "json",
success: function (parsed_json) {
// do the stuff here and call response callback
}
});
}
})

Send php array to jquery ajax and make a each loop from that array

hi actually i read many topic about array and jquery and they all show example using jquery inside the hmtl script tag but what i try to learn is how to read an array sent by php throught ajax inside a js file
here is my php example
$record = array('jazz','rock', 'punk', 'soft', 'metal');
echo json_encode($record);
then here is my ajax
$.ajax({
url: "system/music_list.php",
dataType: 'json',
cache: false,
success: function(response){
// here i want to read the array and make a loop for each element
},
});
thanks if you can help me
try basic for loop with count using length This .. this should help surely.
function ajax_test()
{
$.ajax({
url: "system/music_list.php",
dataType: 'json',
cache: false,
success: function(response)
{
for (var i = 0; i < response.length; i++)
{
alert(response[i]);
}
}
});
}
Try a for loop to loop the records
$.ajax({
url: "system/music_list.php",
dataType: 'json',
cache: false,
success: function(response){
var record;
for(record in response)
{
console.log(response[record]);
});
},
});
Please use below code :
$(response).each(function(key,value){
console.log(value);
});
Here each loop of response array and value get ('jazz',rock,...etc).
try see this, clear solution for your question
https://stackoverflow.com/questions/20772417/how-to-loop-through-json-array-in-jquery
$.each : A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties. Reference documentation
$.ajax({
url: "system/music_list.php",
dataType: 'json',
cache: false,
success: function(response){
//Check if the response is in expected JSON format.
var flag = isJSON(response);
if(flag === true)
{ response = JSON.parse(response); }
//Iterate the Array using for each loop of jquery
$.each(response, function( index, value ) {
console.log( "Index : " + index + "Value : " + value );
});
} // End of success function
}); //End of Ajax
//JSON format check
function isJSON(data) {
var ret = true;
try {
JSON.parse(data);
}catch(e) {
ret = false;
}
return ret;
}
You can get array indexes and values by using .each in jQuery as:
$.ajax({
url: "system/music_list.php",
dataType: 'json',
cache: false,
success: function(response){
$.each(response, function(index,value)
{
console.log(index); // print all indexes
console.log(value); // print all values
});
},
});
<div id="dat" name="dat"></div>
<script type="text/javascript">
$.ajax({ url: "music_list.php",
dataType: 'json',
cache: false,
success:function(response) {
for( res in response) {
document.getElementById('dat').innerHTML+=response[res]+"<br/>";
}
}
});
</script>

Stacking multiple AJAX requests on success (jQuery)

I'm just testing a local application and wanted to make something like this:
Click button, that's easy.
Perform AJAX request and create a database table.
Once the table is created, perform another series of AJAX requests and populate the table according to some parameters gotten from a series of select boxes.
"Animate" the whole thing using a progress bar.
Surprisingly, everything is working fine (apart the last point), but I'm getting some troubles.
The table gets created and populated but, for some reasons, the very last AJAX requests doesn't fire correctly, since it's not passing a parameter correctly.
My ajax requests are ALL asyncronous, if I set them syncronous the whole thing will freeze, but all the requests are executed correctly, even the very last one.
For instance, let's say that I don't want to use asyncronous requests in order to DON'T freeze the page and be able to show a progress bar.
The questions are the following:
Is it possible to call the same script twice?
Is there an efficient way to avoid ajax requests executing before other ajax requests?
After reading a whole bunch of topics here in stackoverflow, I edited my code and tried to:
use jQuery.AJAX prototype instead of jQuery.POST
Set everything asyncronously, in order to don't freeze the page and be able to handle a progress bar
perform the very next AJAX request into the "success" callback of the parent AJAX request.
At this point, I still have another question:
By stacking AJAX requests, is it actually TRUE that everything executed into the "success" callback will be executed AFTER the ajax requests has completed?
This is what I'm performing:
$.ajax({
type: "POST",
url: '../libs/php libraries/agenda.php',
data: {'action':'create>agenda', 'sqlname': createInfo},
processData: true,
dataType: "json",
timeout: 60000,
async: true,
success: function(res) {
$('#popup_content').append(res.log);
var dateList = new Array();
var dateObj = new Date();
var m = dateObj.getMonth();
var Y = dateObj.getFullYear();
for (var i = 1; i <= 31; i++) {
dateList.push(i+"/"+m+"/"+Y);
}
for (var i = 0; i < dateList.length; i++) {
var rs = false;
$.ajax({
type: 'POST',
url: '../libs/php libraries/agenda.php',
data: {'action':'validate>date', 'date': dateList[i]},
processData: true,
timeout: 60000,
async: true,
dataType: "json",
success: function(x) {
$('#popup_content').append(x.log);
if (x.res == 'true') {
rs = dateList[i];
}
if (rs != false) {
$.ajax({
type: 'POST',
url: '../libs/php libraries/agenda.php',
data: {'action':'create>day', 'date': rs, 'sqltable': createInfo},
processData: true,
timeout: 60000,
async: true,
dataType: "json",
success: function(newResult) {
console.log(newResult.res);
$('#popup_content').append(newResult.log);
}
});
}
}
});
}
}
});
the first AJAX request executes correctly, the second one does too, but in the third one (the one with data: {'action':'create>day', 'date': rs, 'sqltable': createInfo}) is getting fired but is missing the parameter rs defined above.
Also, to be clearer, rs is a temporary variable I've defined when I was trying to make the requests outside the "success" callback and when using $.when and $.done, in this case the variable rs is useless, but It won't change anything.
Again, as said above, the whole thing works using a syncronous request, but doesn't by using an asyncronous one.
Moreover, I'm just going to use this script locally, so delays or every problematic related to delays caused by servers and client are not important.
Is there any reason for the last request to don't work with an asyncronous request? if so is there a valuable solution for this case? I've also checked the topics about the queue, but it didn't solve my problem either. For some reasons, asyncronously, the last AJAX requests get just partially fired, since the variable rs is not getting passed correctly.
One solution is to use queue() function. This way you can execute as many functions as you want
var ajaxQueue = $({});
$.ajaxQueue = function(date, ajaxOpts) {
// queue the method. a second call wont execute until this dequeues
ajaxQueue.queue(function(next) {
// for this example I serialize params, but you can save them in several variables
// and concat into ajaxOpts.data
var params = method_that_get_params_and_serialize_them();
ajaxOpts.data = params;
ajaxOpts.complete = function() {
next();
};
$.ajax(ajaxOpts);
});
};
Then your functions have no need of shared vars, with the concurrency conflicts that it causes.
It should be like this:
$.ajax({
type: "POST",
url: '../libs/php libraries/agenda.php',
data: {'action':'create>agenda', 'sqlname': createInfo},
processData: true,
dataType: "json",
timeout: 60000,
async: true,
success: function(res) {
$('#popup_content').append(res.log);
var dateList = new Array();
var dateObj = new Date();
var m = dateObj.getMonth();
var Y = dateObj.getFullYear();
for (var i = 1; i <= 31; i++) {
dateList.push(i+"/"+m+"/"+Y);
}
for (var i = 0; i < dateList.length; i++) {
processDate(dateList[i]);
}
}
});
function processDate(date){
$.ajaxQueue({
type: 'POST',
url: '../libs/php libraries/agenda.php',
data: {'action':'validate>date', 'date': date},
processData: true,
timeout: 60000,
async: true,
dataType: "json",
success: function(x) {
$('#popup_content').append(x.log);
if (x.res == 'true') {
$.ajax({
type: 'POST',
url: '../libs/php libraries/agenda.php',
data: {'action':'create>day', 'date': date, 'sqltable': createInfo},
processData: true,
timeout: 60000,
async: true,
dataType: "json",
success: function(newResult) {
console.log(newResult.res);
$('#popup_content').append(newResult.log);
}
});
}
}
});
};
}

Ajax asynchronous response not loading into div

Here is what bothering me. My code is running on document.ready. I need the request to be asynchronous, meaning async: true
for (var i = 0; i < totalGraphs; i++) {
var kpiId = kpiIds[i];
jQuery.ajax({
type: 'POST',
url: graphUrl,
data: "kpiId="+kpiId+"&divId="+(i+1),
async: true, //if false things are working fine
cache:false,
success: function(response){
document.getDocumentById("graph" + (i + 1)).innerHTML("hello");
},
error:function(XMLHttpRequest, textStatus, errorThrown) {
}
});
}
This request does not put hello in my graphX divs, but whenever i put async: false things are working fine. I really need the request to be asynchronous.
Thanks in advance for any help.
Try this...
for (var i = 0; i < totalGraphs; i++){
(function ajaxCall(index) {
var kpiId = kpiIds[index];
jQuery.ajax({
type: "POST",
url: graphUrl,
data: {
kpiId : kpiId,
divId : index + 1
},
async: true, //if false things are working fine
cache: false,
success: function(response) {
document.getDocumentById("graph" + (index + 1)).innerHTML("hello");
},
error: function(XMLHttpRequest,textStatus,errorThrown) {}
});
})(i);
}
I've wrapped the ajax call in an anonymous function so that the value of i will never change, relative to the ajax call.
I'm guessing the i count is getting mixed up in your loop when success is returned. success will return after the loop has run through and thus this will give an unexpected result.
Can you return the i value that went sent in data in your response then use this in your getDocumentById method? I'm guessing this would fix your issue.
New code to try:
for(var i=0;i<totalGraphs;i++){
jQuery.ajax({
type: 'POST',
url: graphUrl,
data: { kpiId: kpiIds[i], divId: (i+1) },
async: true, //if false things are working fine
cache:false,
success: function(response){
document.getDocumentById("graph" + response.count).innerHTML("hello");
},
error:function(XMLHttpRequest,textStatus,errorThrown){}
});
}
First of all, you are running an ajax call inside a loop. This will be okay if you've turned off the async. But since you've turned on the async, the loop doesn't wait for the ajax to finish its work.
The best thing to do would be to get the values to a global variable using the inner loop ajax and then use the variable to draw the graph later.

Categories