jquery.html array as a selector - javascript

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.

Related

Having a hard time showing results after an AJAX call

Browser: IE 11
PlatForm: SharePoint 2016
I am trying to cache data into an array when page loads, so that the array can be used throughout the rest of my code for efficiency purposes. I have 4 arrays and the data to populate the arrays will be coming form 4 different SharePoint lists. I am using jQuery to make the calls to the lists and to retrieve the data. I believe that the way I have done it is wrong because though the calls are successfully made the arrays are not populated by the time I use them. Here's an excerpt of the code:
var cacheNavData = [];
var cacheSubNavData = [];
var cacheMegaMenuData = [];
var cacheCategoryMenuData = [];
$(document).ready(function(){
getNavData();
getSubNavData();
getMegaMenuData();
getCategoryMenuData();
})
function getNavData(){
var endPointUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbyTitle('"+lName+"')/items";
var headers = {
"accept":"application/json;odata=verbose"
}
$.ajax({
url:endPointUrl,
async:false,
type:"GET",
headers: headers,
success: function success(data) {
cacheNavData = data.d.results;
}
});
}
function getSubNavData(){
var endPointUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbyTitle('"+lName+"')/items?$select=parentNav/URL, parentNav/URLNAME,subLink&$expand=parentNav";
var headers = {
"accept":"application/json;odata=verbose"
}
$.ajax({
url:endPointUrl,
async:false,
type:"GET",
headers: headers,
success: function success(data) {
cacheSubNavData = data.d.results;
}
});
}
function getMegaMenuData(){
var endPointUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbyTitle('"+lName+"')/items";
var headers = {
"accept":"application/json;odata=verbose"
}
$.ajax({
url:endPointUrl,
async:false,
type:"GET",
headers: headers,
success: function success(data) {
cacheMegaMenuData = data.d.results;
}
});
}
function getCategoryMenuData(){
var endPointUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbyTitle('"+lName+"')/items";
var endPointUrl = "_api/web/lists/getbyTitle('"+lName+"')/items";
var headers = {
"accept":"application/json;odata=verbose"
}
$.ajax({
url:endPointUrl,
async:false,
type:"GET",
headers: headers,
success: function success(data) {
cacheCategoryMenuData = data.d.results;
}
});
}
console.log(cacheNavData);
console.log(cacheSubNavData);
console.log(cacheMegaMenuData);
console.log(cacheCategoryMenuData);
Now, I know that the problem is Asynchronous and I'm still trying to wrap my head around it. I've looked at several problems and explanations on this site. I've also looked at different articles and watched videos but I still don't fully get it. In this situation, I know that when I'm looking to check the data in the console.log(), the Ajax call has not returned the data yet. Through all of my readings, I have come to understand that. The part that I'm not getting is the fix or the how do I prevent that from happening. I tried the following to fix this problem but it didn't work. Maybe I did something wrong. Any help would be much appreciated. Thanks!
var cacheNavData = [];
var cacheSubNavData = [];
var cacheMegaMenuData = [];
var cacheCategoryMenuData = [];
$(document).ready(function() {
var cache1 = getData("Navigation", "cacheNavDataVar");
var cache2 = getData("Sub Navigation", "cacheSubNavDataVar");
var cache3 = getData("category menu", "cacheCategoryMenuDataVar");
var cache4 = getData("Mega Menu Category", "cacheMegaMenuDataVar");
$.when(cache1, cache2, cache3, cache4).done(function(results){
if(results){
createNavigation(cacheNavData)
}
})
});
I hope above highlighted line is self explanatory. If you call multiple ajax async : true requests then browser opens new tcp port for every request and as soon it get response from any request, it starts calling ajax success function.

Make array jquery/js

I want to make an array like this. (on alert it gives object)
var playlist = [{"title":"Kalimba","mp3":"http://www.jplayer.org/audio/mp3/TSP-01-Cro_magnon_man.mp3"}];
From:
var playlist = [];
$.ajax({
url: 'url.php',
data: {
album_name: album_name
},
type: 'POST',
success: function( data ) {
var data_array = JSON.parse(data);
for( var i=0; i<data_array.length; i++ ) {
var value = data_array[i].split('::');
playlist.push('{"title":"Kalimba","mp3":"http://www.jplayer.org/audio/mp3/TSP-01-Cro_magnon_man.mp3"},'); // putting the same thing just for testing.
}
alert(playlist);
}
});
Now the new array playlist didn't seem to be working for me. i guess there is something wrong the way i am creating an array like above.
you need to push object instead of object string:
playlist.push({"title":"Kalimba","mp3":"http://www.jplayer.org/audio/mp3/TSP-01-Cro_magnon_man.mp3"});
//------------^---remove the single quote.
Try this one
var playlist =[{"title":"Kalimba","mp3":"http://www.jplayer.org/audio/mp3/TSP-01-Cro_magnon_man.mp3"}];
alert(JSON.stringify(playlist));
Use jQuery.map() for making array.
playlist = $.map(data_array, function(val, i){
splitArr = val.split('::')
return {
'title':splitArr[0],
'mp3':splitArr[1]
}
})
As #Jai said you need to push an object: playlist.push({"title":"Kalimba","mp3":"http://www.jplayer.org/audio/mp3/TSP-01-Cro_magnon_man.mp3"});
Arrays in JavaScript are objects.
You'd be better using the console to log or debug your javascript.
In this fiddle you can see
that the array is created and the object pushed to it but its
still logged as an object.
And since you are using jQuery it has a method isArray() to determine if
something is an array or not.
or you can try like this
var playlist = [];
$.ajax({
url: 'url.php',
data: {
album_name: album_name
},
type: 'POST',
success: function( data ) {
var data_array = JSON.parse(data);
for( var i=0; i<data_array.length; i++ ) {
var value = data_array[i].split('::');
var ArrObj = '{"title":"Kalimba","mp3":"http://www.jplayer.org/audio/mp3/TSP-01-Cro_magnon_man.mp3"},';
playlist.push(ArrObj);
}
alert(playlist);
}
});

Clean way to make Subsequent AJAX Calls to API based on Data

So I have a conceptual question regarding the cleanest way to make subsequent AJAX calls to an API based on the returned data.
A quick example:
A function, which encompasses the call would look like this:
function makeCall(headers, min, max) {
$.ajax({
headers: headers,
url: "https://coolapi.com/data?begIndex" + min + "&endIndex=" + max + "&begTimestamp=1404198000000&endTimestamp=1409554800000",
type: "GET",
dataType: 'JSON'
});
}
makeCall(headers, 0, 20);
The beg / end index (min/max), determine the amount of data I'll get back in the array. The API will only return a maximum of 20 items in the array, but it will also return me a COUNT of how many items total exist in that array. An example of the data returned is below:
{
count = 133;
result = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19];
}
So my next call would be:
makeCall(headers, 20, 40);
and so on so forth, until I got all 133 items from the array.
The question is...what is the cleanest way to continue to make subsequent calls until I've gotten and stored all 133 items from the array? Given that the count could be any number, it's hard to imagine how I can do this. I was thinking of nesting more ajax calls in a "success" function, but it's not scalable if I get back a number like 300.
Does anyone have any advice on how to proceed?
Thanks in advance!
EDIT:
So based on the advice in the comment, I've attemped to make the call recursive--but it doesn't seem to function as intended:
var theData = [];
var minCounter=0;
var maxCounter= minCounter + 20;
function makeCall(headers, min, max) {
$.ajax({
headers: headers,
url: "https://coolapi.com/data?begIndex" + min + "&endIndex=" + max + "&begTimestamp=1404198000000&endTimestamp=1409554800000",
type: "GET",
dataType: 'JSON',
success: function (data) {
theData.push(data.result);
newMin = minCounter + 20;
if (data.count >= theData.length ) {
makeCall(headers, newMin, maxCounter);
}
}
});
}
makeCall(headers, minCounter, maxCounter);
How do properly increment the variable as well as set the flag?
SECOND EDIT:
The method below works using the second comment's suggestion, but there are some issues here as well...
function doAjax(headers, min, dObject) {
var max = min + 20;
$.ajax({
headers: headers,
url: "https://coolapi.com/data?begIndex" + min + "&endIndex=" + max + "&begTimestamp=1404198000000&endTimestamp=1409554800000",
type: "GET",
dataType: 'JSON',
success: function (data) {
results.push(data);
window.count = data.count;
dObject.resolve();
}
});
}
// array that will contain all deferred objects
var deferreds = [];
// array that will contain all results
var results = [];
// make the ajax calls
for (var i = 20; i < 133 ; i+= 20) {
var dObject = new $.Deferred();
deferreds.push(dObject);
doAjax(headers, i, dObject);
}
// check if all ajax calls have finished
$.when.apply($, deferreds).done(function() {
console.log(results);
});
var dObject = new $.Deferred();
doAjax(headers,0, dObject);
First, the data doesn't push to the array in order. There doesn't seem anyway to fix this. Also strangely enough, in the for loop--I have to set the number for it to actually work. Trying to store it in a variable doesn't seem to work as well...Suggestions here?
Here's a working implementation based around the code you started with. Code is commented to help you understand what is happening:
// Change these constants to suit your purposes.
var API_URL = 'https://coolapi.com/data';
var HEADERS = {};
var API_RESULTS_PER_REQUEST = 20;
var MAX_API_CALLS = 20;
// Count API calls to trigger MAX_API_CALLS safety lock.
var apiCalls = 0;
// Function we'll call to get all our data (see bottom).
function collectApiData(begTimestamp, endTimestamp) {
var dataReady = jQuery.Deferred();
var params = {
'begTimestamp': begTimestamp,
'endTimestamp': endTimestamp
};
var datasetsCollected = requestDatasets(params);
jQuery.when(datasetsCollected).then(function(data) {
dataReady.resolve(data);
});
return dataReady;
}
// Makes individual AJAX call to API
function callApi(params, headers) {
var $request = jQuery.ajax({
url: API_URL,
headers: headers,
data: params,
type: 'GET',
dataType: 'JSON'
});
return $request;
}
// Recursive function that makes API calls until data is collected, there is an
// error, or MAX_API_CALLS limit is hit.
function requestDatasets(params, resultsReady, resultsFetched) {
resultsReady = ( resultsReady !== undefined ) ? resultsReady : jQuery.Deferred();
resultsFetched = ( resultsFetched !== undefined ) ? resultsFetched : [];
// Trigger safety to avoid API abuse
if ( apiCalls >= MAX_API_CALLS ) {
console.error('Exceeded max API calls:', MAX_API_CALLS);
resultsReady.resolve(resultsFetched);
}
// Set index data
params.begIndex = resultsFetched.length;
params.endIndex = resultsFetched.length + API_RESULTS_PER_REQUEST;
// Request dataset from API
var apiRequest = callApi(params, HEADERS);
apiCalls += 1;
// Callback once API request has completed and data is ready
jQuery.when(apiRequest).done(function(data) {
var apiResultCount = data.count;
resultsFetched = resultsFetched.concat(data.result);
console.debug('Fetched', resultsFetched.length, 'of', apiResultCount, 'API results');
if ( apiResultCount > resultsFetched.length ) {
console.debug('Making another API call');
requestDatasets(params, resultsReady, resultsFetched);
}
else {
console.debug('Results all fetched!');
resultsReady.resolve(resultsFetched);
}
});
jQuery.when(apiRequest).fail(function(data) {
console.error('API error: returning current results.');
resultsReady.resolve(resultsFetched);
});
return resultsReady;
}
// Run script
var dataReady = collectApiData('1404198000000', '1409554800000');
jQuery.when(dataReady).then(function(data) {
console.log(data);
});
Here's a working fiddle that mocks the API using httpbin.org:
http://jsfiddle.net/klenwell/mfhLxun2/

Handling Multiple AJAX Callbacks with Unique Variables

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);
});
}

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