Handling Multiple AJAX Callbacks with Unique Variables - javascript

I'm using JQuery's implementation of AJAX to access multiple JSON and different URLS. I have an array of names that each URL corresponds to, and would like to be able to reference the corresponding name that goes with the corresponding JSON file in the callback funciton of the AJAX request.
I've written a sample of my code so far for testing:
var nameList = ['Tom', 'Neil', 'Jane'];
for(var i = 0; i < nameList.length; i++){
var currentName = nameList[i];
var newURL = urlFromName(currentName)
$.ajax({
type: 'GET',
url: newURL,
dataype: 'jsonp'
}).always(function(data,status, error){
console.log(currentName);
console.log(data);
});
}
The code outputs:
- Neil
- Object
- Neil
- Object
- Neil
- Object
I am looking for each Object to be printed out with the corresponding name from the nameList that I have supplied it. How would I go about doing this?

Try this:
var nameList = ['Tom', 'Neil', 'Jane'];
for(var i = 0; i < nameList.length; i++){
var currentName = nameList[i];
var newURL = urlFromName(currentName)
$.ajax({
type: 'GET',
url: newURL,
dataype: 'jsonp',
currentName: currentName // <-- Add this here
}).always(function(data,status, error){
console.log(this.currentName); // <-- Use the 'this' to get it
console.log(data);
});
}

Related

jquery.html array as a selector

Below is my code for getting a data from api for 2 different URLs. The result is positive when I use $('#resultDiv1').html instead of opts[j].html. On using opts[j].html, I am getting error as opts[j].html is not a function'. Where is the mistake? Please help me.
var domain = "https://example.com/api#token=";
var detail = "/some_data"
$(document).ready(function() {
var token = ['260105', '49409' ];
var resultElement1 = $('#resultDiv1');
var resultElement2 = $('#resultDiv2');
var opts = ["resultElement1", "resultElement2"];
for (j=0; j<1; j++){
$.ajax({
url: domain + token[j] + detail,
method: 'get',
dataType: 'json',
success: function(response) {
opts[j].html(response.data.candles[response.data.candles.length - 1][4]);
}
})
}
});
That won't work because "resultElement1" and "resultElement2" are two different strings in the opts array. To use the selected elements, you need to create array using the variables resultElement1 and resultElement2, like this:
var opts = [resultElement1, resultElement2];
Also, your for loop will only work for resultElement1, because you end the iteration as soon as j becomes 1.

Table sorting fix

I have data in a table coming from multiple json api links.
my code currently is
<script src="js/1.js"></script>
<script src="js/2.js"></script>
Above this is a table code. Allowing the table to be sorted. It only has <th> and <thead> tags.
The issue as it stands looks like this:
I'm wanting ideally the price field to be sorted. below is the inside of the JS files
1.js
$.ajax({
type : 'GET',
crossDomain : true,
dataType : 'json',
url : 'api link here',
success : function (json) {
//var json = $.parseJSON(data);
for(var i=0; i<json.results.length; i++) {
var section = json.results[i].section;
var no = json.results[i].avalible;
var price = json.results[i].price;
var button = "<button class='redirect-button' data-url='LINK'>Compare</button>";
$("#tableid").append("<tbody><tr><td>"+section+"</td><td>"+no+"</td><td>"+price+"</td><td>"+button+"</td></tr></tbody>");
$("#tableid").find(".redirect-button").click(function(){
location.href = $(this).attr("data-url");
});
}
},
error : function(error){
console.log(error);
}
});
and here is the 2nd js file
$.ajax({
type : 'GET',
crossDomain : true,
dataType : 'json',
url : '2nd api',
success : function (json) {
//var json = $.parseJSON(data);
for(var i=0; i<json.results.length; i++) {
var section = json.results[i].section;
var no = json.results[i].avalible;
var price = json.results[i].amount;
var button = "<button class='redirect-button' data-url='LINK'>Click Here</button>";
$("#tableid").append("<tbody><tr><td>"+section+"</td><td>"+no+"</td><td>"+price+"</td><td>"+button+"</td></tr></tbody>");
$("#tableid").find(".redirect-button").click(function(){
location.href = $(this).attr("data-url");
});
}
},
error : function(error){
console.log(error);
}
});
Now here is what i believe is the code to sort the js files in the table, Issue is I have no idea where to put it.
var sortTable = function(){
$("#tableid tbody tr").detach().sort(function(a,b){
//substring was added to omit currency sign, you can remove it if data-price attribute does not contain it.
return parseFloat($(a).data('price').substring(1))- parseFloat($(b).data('price').substring(1));
})
.appendTo('#tableid tbody');
};
And
for(var i=0; i<json.results.length; i++) {
....
}
sortTable();
I would use a tablesorter jquery plugin but i would rather not.
Since you're pulling data from two ajax requests, perhaps it will be better to store both results in one global array that you can sort and loop through to build your table in price order.
var resultsArray = new Array();
for (var i = 0; i < json.results.length; i++) {
resultsArray.push(json.results[i]);
}
resultsArray.sort(function(a,b) {
return a.price - b.price;
});
for (var i = 0; i < json.results.length; i++) {
//print your table here
var price = resultsArray[i].price;
//etc...
}
I fully demonstrated this in a fiddle
is it possible for you to take both of the json reponses, sort them in order by price, and then add them to the dom? This way you don't have to access the dom so much just to sort your data?
This would go something like this, if you're using jQuery. Basically once both of your ajax requests resolve you can do whatever with the data you have. Fromt here you can merge them, sort them, and then run your piece to populate the table.
var urlDatas = [];
$.when(
$.getJSON(someUrl, function(data) {
urlDatas.push(data);
}),
$.getJSON(someOtherUrl, function(data) {
urlDatas.push(data);
})
).then(function() {
//not completely sure if extend returns a value or just mutates, target.
finalData = $.extend(true, {}, urlDatas[0], urlDatas[1]);
//run a sort on that data
sortData(finalData);
//add it to your dom
insertData(finalData);
});

How to prevent call from jQUery AJAX from 'losing' scope

I am working with jQuery and doing some prototyping.
In my app, I use jQuery.ajax() to get some HTML from the server, then it needs to be inserted into a DIV in the page.
Here are the relevant parts of my code:
SONGS_UPLOADER.prototype.FileSelectHandler = function(e) {
this.FileDragHover(e);
var files = e.target.files || e.dataTransfer.files;
var target = this.target;
var artist_id = this.artist_id;
var album_id = this.album_id;
var onComplete = this.onSongUploaded;
for ($x = 0; $x < files.length; $x ++) {
var file = files[$x];
jQuery.ajax({
type: 'post',
dataType : 'html',
url: ajaxurl,
data: {action: 'add_new_song', artist_id: artist_id, album_id: album_id, title:file.name},
success: function(DATA)
{
onComplete(DATA);
}
});
}
}
SONGS_UPLOADER.prototype.files;
SONGS_UPLOADER.prototype.onComplete;
SONGS_UPLOADER.prototype.album_id;
SONGS_UPLOADER.prototype.artist_id;
SONGS_UPLOADER.prototype.target;
SONGS_UPLOADER.prototype.onSongUploaded = function(DATA){
var song = jQuery(DATA);
//console.log(target.find('.songs_list'));
this.target.find('.songs_list').append(song);
new SONGS_MANAGER(song, file);
}
In the AJAX complete function I have tried the following:
onComplete(DATA) - this calls the onSOngUploaded function, but the 'this.target' in onSongUploaded is undefined.
this.onSongUploaded and onSongUploaded - got an error that onSongUploaded does not exist.
jQuery.proxy(this.onSongUploaded (and) onSongUploaded, this) - got an error that onSOngUploaded does not exist.
I know it probably has something to do with the scope when using the jQuery.ajax() function, but I just can't figure out how to resolve it.
How can I adjust my code so the onSongUploaded function is called and respects the 'this' keyword on the SONGS_UPLOADER object?

Append Order - jQuery

I am trying to get the string to order by how it is displayed (red,blue,orange,black). For some reason, it will append the order randomly. For Example: it would output (blue,orange,red,black). Any help would be great. Thanks.
var tCookie = "red,blue,orange,black";
var Cookies = tCookie.split(',');
if (Cookies) {
for (var i = 1; i <= Cookies.length; i++) {
var dataString = "TabId="+Cookies[i]+"";
$.ajax({
type: "POST",
url: "includes/tab.php",
data: dataString,
cache: false,
success: function(html){
$("#Dynamic_Tab").append(html).children(':last').hide().fadeIn("fast");
}
});
}
}
You could have a list of requests and responses, and start appending when all are done, so that the order is always correct:
var deferreds = [],
results = [];
for (var i = 1; i <= Cookies.length; i++) {
(function(i) { // to freeze i
var dataString = "TabId="+Cookies[i]+"";
deferreds.push($.ajax({
type: "POST",
url: "includes/tab.php",
data: dataString,
cache: false,
success: function(html){
results[i] = html; // insert at the synchronous position
}
}));
})(i);
}
$.when.apply($, deferreds).then(function() {
$.each(results, function(i, html) {
$("#Dynamic_Tab").append(html).children(':last').hide().fadeIn("fast");
});
});
You can use deferred objects here to only append the HTML after all of the AJAX requests come back:
//create array to store XHR objects that will resolve when the AJAX requests return
//also create an object to store the AJAX responses
var jqXHRs = [],
responses = {};
//iterate through each of the cookie indexes
$.each(cookies, function (index, value) {
//create the dataString and cache the value of this index so it can be used in the success callback for the AJAX request associated with this index
var dataString = "TabId=" + value,
thisValue = value;
//store an empty string in the output variable for the current index, this keeps it's place in-line
responses[thisValue] = '';
//do the AJAX request and store it's XHR object in the array with the rest
jqXHRs[jqXHRs.length] = $.ajax({
type : "POST",
url : "includes/tab.php",
data : dataString,
cache : false,
success : function (html) {
//now that the AJAX request has returned successfully, add the returned HTML to the output variable for this index
responses[thisValue] = html;
}
});
});
//wait for all of the XHR objects to resolve then add all the HTML to the DOM
$.when(jqXHRs).then(function () {
//all of the AJAX requests have come back and you can now add stuff to the DOM
var $element = $("#Dynamic_Tab");
$.each(responses, function (index, value) {
$element.append(value).children(':last').hide().delay(index * 250).fadeIn(250);
}
});
The .delay() is so that each new row will fade in, in order.

Problem understanding javascript multi-dimension arrays

I want to get some values out of TinyMCE textboxes, along with IDs. Then post these via ajax to the server.
jQuery 1.4 and JSON library are loaded
var send_data = [];
$('.contact_check').each(function(i, item) {
var this_id = $(item).attr('id');
var msgbox = tinyMCE.get('contacts[' + this_id + '][message]');
var content = addslashes(msgbox.getContent());
send_data[i]["id"] = this_id;
send_data[i]["content"] = escape(content);
});
var encoded = JSON.stringify(send_data);
$.ajax({
type: 'POST',
url: 'http://localhost/test.php',
data: encoded,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function() {
alert('jay');
}
});
Firstly,
send_data[i]["id"] = this_id;
send_data[i]["content"] = escape(content);
does not seem to work. It says send_data[i] undefined. I've also tried:
send_data[this_id] = escape(content);
That does not seem to work either. The JSON string returns as []. What am I doing wrong?
You're not really making a multi-dimensional array. You're making an array of objects. Either way, before you can set an attribute or array element of something at send_data[i], you have to make send_data[i] be something.
send_data[i] = {};
send_data[i]['id'] = this_id;
send_data[i]['content'] = escape(content);
or, better:
send_data[i] = {
id: this_id,
content: escape(content)
};
You have to make each send_data[i] an object first:
$('.contact_check').each(function (i, item) {
var this_id = $(item).attr('id');
var msgbox = tinyMCE.get('contacts['+this_id+'][message]');
var content = addslashes(msgbox.getContent());
send_data[i] = {};
send_data[i]["id"] = this_id;
send_data[i]["content"] = escape(content);
});

Categories