I have an ajax function hitting the Twitch API to find "Starcraft" streams.
$.ajax({
type: 'GET',
url: 'https://api.twitch.tv/kraken/search/streams?q=starcraft',
headers: {'Client-ID': 'xxx'},
success: function(json) {
console.log(json);
}});
This returns Object {_total: 108, _links: Object, streams: Array[9]}. I want streams array to hold all streams (all 108).
I've tried adding limit and offset to url like so:
https://api.twitch.tv/kraken/search/streams?limit=100&offset=0&q=starcraft but this will obviously only work for cases where there are under 100 streams. Anyone familiar with the Twitch API, is there like a limit=max kind of thing? If not, what is the workaround?
The following is based on my comment to your question and should get you started. I;ve worked on the assumption that offest is eqivalent to page. Note that the code is untested and a starting point only.
Also make sure to handle a failure from the ajax call so you don't get stuck in an infinate loop.
fucntion GetAllStreams(){
var arrStreams = [];
var offset = 0;
var total = -1;
while(total < 0 || arrStreams.length < total)
{
$.ajax({
type: 'GET',
url: 'https://api.twitch.tv/kraken/search/streams?limit=100&offset=' + offset++ + '&q=starcraf',
headers: {'Client-ID': 'xxx'},
success: function(json) {
arrStreams.push(json.streams);
console.log(json);
console.log(arrStreams);
}});
}
retrun arrStreams;
}
Related
I make ajax calls every minute in my platform, necessary because the information changes every minute for n elements. However after 400 calls my platform copmmence to crash so I would like to know, once made an ajax call, would there be a way to delete the data retrieved after use?
or if you have other solutions.
cordially.
function updateMarker() {
for (i = 0; i < ArrMarker.length; i++) {
$.ajax({
type: "GET",
url: "ajax-RT.php?IMEI=" + imeis[i],
dataType: "text",
success: function(params) {
crudMarker(params);
}
});
loading(i);
evennements()
}
$(".valueLoad").text("100%");
$(".fullsize-loading").hide();
}
window.setInterval(updateMarker, 60000);
I've written a few lines of code to tackle the following problem:
Get the TwitchTV UserID based on the username. The usernames are in an arrray. After hitting a button a GET AJAX request will be called to GET the UserID and to push it in another array and the call to the API will made via AJAX after hitting a button.
My problem is that if I hit the button again the usersID are in wrong order.
If I set async: false, it works.
Is this problem because of Asynchronous AJAX? What would be the approach for a valid fix? Use callback? A hint in the right direction would be appreciated.
The comments in the code are for testing.
Code:
<script>
var users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "spicyjewlive"];
clientID = "?client_id=XXX";
userID = [];
userStatus = [];
for(var i=0; i<users.length; i++){
idCall(users[i]);
};
function idCall (data){
$.ajax({
type: "GET",
url: "https://api.twitch.tv/kraken/users/" + data + clientID,
async: false,
cache: false,
dataType: "jsonp",
success: function (data){
console.log(data._id);
},
error: function (data) {
console.log("error");
}});
};
</script>
Use an array of request promises and update the dom after all those are resolved. The results will be in same order as original users array
var requestPromises = users.map(idCall);
$.when.apply(null, requestPromises).then(function(){
var dataArray = [].slice.call(arguments);
// now loop over data array which is in same order as users
dataArray.forEach(function(userData){
// do something with each userData object
});
}).fail(function(){
console.log("Something went wrong in at least one request");
});
function idCall(user) {
// return the ajax promise
return $.ajax({
url: "https://api.twitch.tv/kraken/users/" + user + clientID,
dataType: "jsonp"
}).then(function(data) {
// return the data resolved by promise
return data;
});
};
What would be the approach for a valid fix?
I think #charlieftl answer is a good one. I don't think I can really improve on this. I've mainly added this to try and explain your difficulties here. As I mentioned in a previous question you posted, you need to read and understand How do I return the response from an asynchronous call?.
If you had control of the server side then a simpler option is to send the array server side in order and use this to maintain the order, but your using a third party API so this isn't really practical.
A simpler option would be to use a callback method:
var users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "spicyjewlive"];
var clientID = "?client_id=XXX";
var userID = [];
var userStatus = [];
idCall(users);
function idCall (users, x=0){
if (x < users.length)
{
var data = users[x];
$.ajax({
type: "GET",
url: "https://api.twitch.tv/kraken/users/" + data+ clientID,
cache: false,
dataType: "jsonp",
success: function (data){
console.log(data._id);
},
error: function (data) {
console.log("error");
}})
.then(function(){
idCall(users, x++);
});
}
};
though like I said, charlies answer is better. This will guarantee the order and won't lock the UI. But it's slow.
Is this problem because of Asynchronous AJAX?
Yes, well asynchronous processing on a server and ordering.
When you first this open up the network panel of your debugging tool and watch the HTTP requests. What you'll see is a load of requests getting sent off at the same time but returning in different orders. You cannot guarantee the response order of a async request. It depends on the server response time, load, etc.
Example:
These request we're sent in order A,B,C,D,E,F,G but the responses we're received in B,C,E,F,G,D,A this is the nub of your problem.
Setting async to false does this:
Now no request will be sent until the previous has returned but. So stuff is sent A-G and returns A-G but this is A LOT slower than the previous example (the graphs here aren't to scale, I struggled to capture a good async:false example as I never use it, see reasons below).
Never do this (pretty much ever). What will happen is the UI thread will become locked (Javascript/browsers are single threaded, mostly) waiting for an external call and your web site will become unresponsive for long periods of time. Locking this thread doesn't just stop Javascript, it stops the entire site, so links don't work, hover overs, everything, until the async call returns the thread back to the UI.
Yes, it is because of the AJAX calls. One AJAX call might finish before the other and therefore the different order.
An obvious solution is to use jQuery promises but another solution to this problem could be that you sort your array after your AJAX calls have been completed.
You can sort your array according to the username string like this:
data.sort();
If you have an array of objects, which you don't in the example code, you can sort it like this:
data.sort(function (a, b) { return (a.Name > b.Name) ? 1 : ((b.Name > a.Name) ? -1 : 0); } );
After going through the comments, I thought to give some more code that can a better idea on how to solve this.
<script>
var users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "spicyjewlive"];
clientID = "?client_id=XXX";
userID = [];
userStatus = [];
var count = 0;
for(var i=0; i<users.length; i++){
idCall(users[i]);
}
function idCall (data){
$.ajax({
type: "GET",
url: "https://api.twitch.tv/kraken/users/" + data + clientID,
async: false,
cache: false,
dataType: "jsonp",
success: function (data){
console.log(data._id);
userID.push(data._id);
count++;
if( count === users.length - 1 ) {
userID.sort();
}
},
error: function (data) {
console.log("error");
}
});
}
I created a site which load every few seconds data from multiple sources via AJAX. However I experience some strange behavior. Here is the code:
function worker1() {
var currentUrl = 'aaa.php?var=1';
$.ajax({
cache: false,
url: currentUrl,
success: function(data) {
alert(data)
},
complete: function() {
setTimeout(worker1, 2000);
}
});
}
function worker2() {
var currentUrl = 'aaa.php?var=2';
$.ajax({
cache: false,
url: currentUrl,
success: function(data) {
alert(data)
},
complete: function() {
setTimeout(worker2, 2000);
}
});
}
The problem is that many times, one of the workers returns NaN. If I change the frequency of calls for, lets say, 2000 and 1900, then everything is working ok and I got almost no NaN results. When those frequencies are same, I get over 80% NaN results for one of the calls. It seems like the browser cannot handle two requests called at exact same time. I use only those two workers, so the browser shouldn't be overloaded by AJAX requests. Where is the problem?
Note that the aaa.php works with the mySql database and do some simple queries base on parameters in url.
All you need is $.each and the two parameter form of $.ajax
var urls = ['/url/one','/url/two', ....];
$.each(urls, function(i,u){
$.ajax(u,
{ type: 'POST',
data: {
answer_service: answer,
expertise_service: expertise,
email_service: email,
},
success: function (data) {
$(".anydivclass").text(data);
}
}
);
});
Note: The messages generated by the success callback will overwrite
each other as shown. You'll probably want to use
$('#divid').append() or similar in the success function.
Maybe, don't use these workers and use promises instead like below? Can't say anything about the errors being returned though without looking at the server code. Below is working code for what it looks like you are trying to do.
This is a simple example but you could use different resolvers for each url with an object ({url:resolverFunc}) and then iterate using Object.keys.
var urls = [
'http://jsonplaceholder.typicode.com/users/1',
'http://jsonplaceholder.typicode.com/users/2',
'http://jsonplaceholder.typicode.com/users/3',
'http://jsonplaceholder.typicode.com/users/4',
'http://jsonplaceholder.typicode.com/users/5',
'http://jsonplaceholder.typicode.com/users/6',
'http://jsonplaceholder.typicode.com/users/7'
]
function multiGet(arr) {
var promises = [];
for (var i = 0, len = arr.length; i < len; i++) {
promises.push($.get(arr[i])
.then(function(res) {
// Do something with each response
console.log(res);
})
);
}
return $.when(promises);
}
multiGet(urls);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
JQuery Snippet
// THE FOUR URL'S TO ADD THE TOTAL SHARES
var Gal_All = "Link One";
var Gal_S_1 = "Link Two";
var Gal_S_2 = "Link Three";
var Gal_S_3 = "Link Four";
$.ajax({
type: 'GET',
url: 'https://graph.facebook.com/' + Gal_All,
success: function(data) {
showCount(data);
}
});
var fbshares;
var fbcomments;
function showCount(responseText) {
var json = responseText;
fbshares = json.shares;
fbcomments = json.comments;
$('#fb-share-count').html(fbshares);
if (fbcomments) {
$('#TotalComments').html(fbcomments + ' comments');
}
showTotal();
}
function showTotal() {
if (!tweets) {
tweets = 0
}
if (!fbshares) {
fbshares = 0
}
if (tweets !== undefined && fbshares !== undefined)
$('#total-share-count').html(tweets + fbshares);
}
For fetching data from one Facebook API I have achieved however my gallery is split up into four pages (Gal_All = all images and Gal_S_1, Gal_S_2, Gal_S_3 = categorized)
Alike I have achieved with my Twitter counter adding for all four pages, I would like to do for Facebook so it is not showing the shares for that page, but all four of the pages.
Please Note: Comments fetch only needs to be from Gal_All
First of all, you can request API data for multiple objects using
/?ids=http://example.com/1,http://example.com/2,http://example.com/3
Now since you want comments as well for your 4th URL, that still needs an extra API request (unless you want to fetch comments for the other three as well, just to throw them away, but that would not make much sense) – but you could use a batch request to at least get those two different API calls done with one single HTTP request. After all, the HTTP request is what takes most of the time in making a request to the API, so if speed is the factor you put the most emphasis on (and why wouldn’t you, users don’t like to be kept waiting), I think this is the best way to go. (Using a promise might be fine from a pure “aesthetic” point of view, but it doesn’t change the fact that multiple HTTP requests are quite slow.)
Use a promise:
var count = 0;
$.when(
$.ajax({
type: 'GET',
url: 'https://graph.facebook.com/' + Gal_All,
success: function(data) {
count += data;
}
});
$.ajax({
type: 'GET',
url: 'https://graph.facebook.com/' + Gal_S_1,
success: function(data) {
count += data;
}
});
$.ajax({
type: 'GET',
url: 'https://graph.facebook.com/' + Gal_S_2,
success: function(data) {
count += data;
}
});
$.ajax({
type: 'GET',
url: 'https://graph.facebook.com/' + Gal_S_3,
success: function(data) {
count += data;
}
});
).then(function() {
showCount();
});
I am looking to send a number of different queries via $.ajax as JSON.
I have stored these queries in an object using the following:
var objectName = {
"name1": {
"queryName": "longname1",
"queryAction": "JSONtoSend"
},
"name2": {
"queryName": "longname2",
"queryAction": "JSONtoSend"
},
};
I am then going through the queryActions and setting them:
for (var i = 0, len = Object.keys(objectName).length; i < len; ++i) {
var indexName = Object.keys(objectName)[i];
objectName[indexName].queryAction = "";
var JSONtoTransfer = objectName[indexName].queryAction;
}
$.ajax({
type: "POST",
url: 'URL',
data: JSONtoTransfer,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(dataReturn){
alert(dataReturn.blah);
}
});
I am unable to set the var JSONtoTransfer. It gives me an unexpected [ error. How do I get around this? I get the same error if I enter it straight into the data parameter of $.ajax.
The code I am using is storing the queries in the object correctly, but I need a way to iterate through them all and send via $.ajax.
Thank you for the help. This code is probably not the most efficient way of doing things, so if anyone has any advice, it's more than welcome too :-)
So I wrote the original code wrong, the $.ajax call should be included in the for statement. So it actually iterates....
Anyway, what I found to work was creating an array, pushing the queryAction into it and then stringifying it...
Few problems:
JSONtoTransfer is out of scope of your ajax call. If you want to populate JSONtoTransfer on every iteration and make an ajax request with this different value each time - put the ajax call inside the for loop (although I would seriously consider refactoring this so that you make one ajax call, and deserialize it differently (if it's your server-side code handling it))
You're setting objectName[indexName].queryAction to an empty string, then assigning this value to JSONtoTransfer (now always going to be an empty string)
You have your for syntax a bit muddled up. Best practice would be to change
for (var i = 0, len = Object.keys(objectName).length; i < len; ++i) {
to
for (var i = 0; i < Object.keys(objectName).length; ++i) {
i.e. there's no need to keep initialising len to the same value. NOTE: This is more for readability, not (so much) performance. If you had another use for len inside the loop this advice wouldn't apply.
Your variable objectName is in fact JSON data already. I might be wrong but I think this should work (with less code):
var jsonData = {
"name1": {
"queryName": "longname1",
"queryAction": "JSONtoSend"
},
"name2": {
"queryName": "longname2",
"queryAction": "JSONtoSend"
},
};
//Post with AJAX
$.post('url.php', jsonData, 'json')
.done(function(data) {
alert('Succes!')
})
.fail(function(data) {
alert('Failed!')
});
//This does the same (Post with AJAX)
$.ajax({
url: 'url.php', //Get action attribute of the form
type: "POST",
data: jsonData,
dataType: "json",
.done(function() { //or success: function() {
alert( "success" );
})
.fail(function() { //or error: function() {
alert( "error" );
})
.always(function() { //or beforeSend: function() {
alert( "complete" );
});
});
I am not sure what you want but as pointed out by others there are many issues with your code, but i think you want to execute ajax call one after the other iteratively. if that is what you want then take a look at jQuery deffered -docs are here.Hope that helps