Scope and Order AJAX Callbacks - javascript

This code needs to 1) check if users are online 2) get their information from a slightly different URL and 3) output both to HTML. It works, but inconsistently. In some cases when running the function for outputting the HTML it says that the data from the first request (online or not) is undefined. Right now streamData and userData are globals. But I wish I could get it to work without that. Having issues getting both data sources to consistently be available in the same place at the same time.
var getOnline = function(){
for (var i = 0; i < twitchFaves.length; i++) {
userName = twitchFaves[i];
streamAjaxOnline(userName);
}
}
var streamAjaxOnline = function(userName){
$.ajax({
type : 'GET',
url : "https://wind-bow.gomix.me/twitch-api/streams/" + userName,
dataType : 'jsonp',
success : function(twitchData) {
streamData = twitchData;
if (streamData.stream){
userAjaxOnline(userName);
}
}
});
}
var userAjaxOnline = function(userName){
$.ajax({
type : 'GET',
url : "https://wind-bow.gomix.me/twitch-api/users/" + userName,
dataType : 'jsonp',
success : function(twitchData) {
userData = twitchData;
displayTwitchOnline(streamData, userData);
}
});
}

Right now streamData and userData are globals
That's really bad. It means that multiple calls to the functions will share the same variables and overwrite the results of each other.
But I wish I could get it to work without that.
That's relatively easy: Pass the data to the functions instead. A very simple solution would be:
var streamAjaxOnline = function(userName) {
$.ajax({
type: 'GET',
url: "https://wind-bow.gomix.me/twitch-api/streams/" + userName,
dataType: 'jsonp',
success: function(twitchData) {
if (streamData.stream) {
userAjaxOnline(userName, streamData); // pass streamData here
}
}
});
}
var userAjaxOnline = function(userName, streamData) { // accept streamData here
$.ajax({
type: 'GET',
url: "https://wind-bow.gomix.me/twitch-api/users/" + userName,
dataType: 'jsonp',
success: function(twitchData) {
// no need to store userData if you only use it here
displayTwitchOnline(streamData, twitchData);
}
});
}

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

What is the right way to use "context:..." in an AJAX call?

So I'm aware that there are a big amount of threads about AJAX and the use of the context but after hours of reading and trying I open a new Thread.
So I have this (shorten version) javascript function:
this.CallService = function () {
var Type = this.Type;
var Url = this.Url;
var Data = this.Data;
var ContentType = this.ContentType;
var DataType = this.DataType;
var ProcessData = this.ProcessData;
var ClipUrl = this.ClipUrl;
var CountMax = this.CountMax;
var Callback = this.Callback;
var SucceededServiceCallback = this.SucceededServiceCallback;
var FailedServiceCallback = this.FailedServiceCallback;
return $.ajax({
type: Type, //GET or POST or PUT or DELETE verb
url: Url, // Location of the service
data: Data, //Data sent to server
contentType: ContentType, // content type sent to server
dataType: DataType, //Expected data format from server
processdata: ProcessData, //True or False
context: this,
}).done(function (msg) {//On Successfull service call
SucceededServiceCallback(this, msg);
}).fail(function (msg) {
FailedServiceCallback(this, msg);
});
}
The Important part here are the context: this and the two callbacks done and fail. Im those two callbacks I give the this context to my callback functions:
this.SucceededServiceCallback = function (context, result) {
if (null != context) {
UpdateDebugInfo(context, "succeeded: " + context.DataType + " URL: " + context.Url + " Data: " + context.Data + " Result: " +result);
}
if (context != null && context.DataType == "json" && result != null && context.Callback != null) {
context.Callback(context, result);
}
}
Here the important part is that I use the context to see access the variables DataType, Callback, Url etc.
The Problem now is that the context is set to the last context used (it's an asynchron call so all the variable are the variable from the last call). So I'm pretty sure something is wrong with that context: this, part. I just don't know how to use this right. Thanks for your help.
tl;dr:
I use context: this in an Ajax call. Context is always set to the last "this" called. I want to use the "this" of the call.
You are "caching" all your variables before you fire each request, but in your SucceededServiceCallback function you are inspecting this.XXX - which is not the var Type it looks like you are expecting, but the actual this.Type itself.
What you could do is put these properties into an object and pass it as context, rather than your main object:
this.CallService = function () {
var context = {
Type : this.Type,
Url : this.Url,
Data : this.Data,
ContentType : this.ContentType,
DataType : this.DataType,
ProcessData : this.ProcessData,
ClipUrl : this.ClipUrl,
CountMax : this.CountMax,
Callback : this.Callback
};
var SucceededServiceCallback = this.SucceededServiceCallback;
var FailedServiceCallback = this.FailedServiceCallback;
return $.ajax({
type: Type, //GET or POST or PUT or DELETE verb
url: Url, // Location of the service
data: Data, //Data sent to server
contentType: ContentType, // content type sent to server
dataType: DataType, //Expected data format from server
processdata: ProcessData, //True or False
context: context,
}).done(function (msg) {//On Successfull service call
SucceededServiceCallback(this, msg);
}).fail(function (msg) {
FailedServiceCallback(this, msg);
});
}

JQuery won't pass data labeled sessid when calling drupal service module

Hey all I am working on a json call that will implement Drupal's services module with json. I am using jquery's ajax function to call the function but I am getting an error stating that no parameters are being passed. When I look at the query string being posted I notice that sessid is not being passed even though its with the parameters. Below is what Im running.
// JavaScript Document
$(document).ready(function() {
function drupalConnect(src) {
$.ajax({
url: src,
type: 'POST',
data: {
method: 'system.connect'
},
success: function(data) {
return data["result"]["sessid"];
}
});
}
function getTimestamp() {
return Math.round((new Date).getTime() / 1000);
}
function randString(length) {
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
var randomstring = '';
for (var i = 0; i < length; i++) {
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum, rnum + 1);
}
return randomstring;
}
var session_id = drupalConnect('http://localhost/drupal/services/json-rpc');
var nonce = randString(10);
var timestamp = getTimestamp();
var username = "markusgray";
var password = "Markus1990";
var key = '2ae0392e0aebbfeeddefcc962ea1924f';
var domain = 'localhost';
var hashObj = new jsSHA(timestamp + ";" + domain + ";" + nonce + ";user.login", "TEXT");
var hash = hashObj.getHMAC(key, "TEXT", "SHA-256", "HEX");
var parameters = {
hash: hash,
domain_name: domain,
domain_time_stamp: timestamp,
nonce: nonce,
sessid: session_id,
username: username,
password: password
};
var par = JSON.stringify(parameters);
$.ajax({
url: 'http://localhost/drupal/services/json-rpc',
type: 'POST',
dataType: 'json',
data: {
method: 'user.login',
params: par
},
success: function() {
}
});
});​
drupalConnect doesn't return anything, also the return from the success callback is just thrown away. The best way to use the data returned from an ajax call is to use it in thee callback itself.
function drupalConnect(src){
$.ajax({
url: src,
type: 'POST',
data:{method:'system.connect'},
success: function(data){
var session_id = data["result"]["sessid"];
//use session_id here
}
});
}
It is because of the Asynchronous ajax, let me elaborate, to get the session_id you are making an ajax call. At the moment it will send the request, but it wont ensure that the session_id will be assigned at that moment. Hence when you making the second ajax call, the session_id may not be assigned for a value.
There are two workarounds for this,
One is, making the first ajax call with an option async:false and assign the value within the success call, something like
var session_id;
function drupalConnect(src) {
$.ajax({
url: src,
type: 'post',
async : false,
data: {
method: 'system.connect'
},
success: function(data) {
session_id = data["result"]["sessid"];
}
});
};
DEMO
The second one and preferred way is, use of deferred objects, something like
$.when(
// make your first ajax request
).then(function(data) {
session_id = data["result"]["sessid"];
// make your second ajax call
});​
DEMO

backbone javascript setTimeOut method

im have a problem with method setTimeOut that call the function self and set a delay, the function should be called again and again after every request is done but it only runs once. It works without using backbone.js tho, don't know it doesnt work after integration with backbone.js. Any help is appreciated!
So this is a function in client that runs a GET request gets data from server, the request runs in a time interval(decided in the server), as soon as a data comes in, client gets it and the request runs again after.
getRequest:function() {
var XHR = $.ajax({
url: '/nextdocument',
type: 'GET',
async: true,
cache: false,
timeout: 11000,
success:function(data) {
var name = data.description;
var price = data.price;
console.log("read--> " + name + price);
setTimeout("this.getRequest", 1000);
if (data.ok == "true") {
data["ok"] = data.ok;
$.ajax(
{
url: "/customerdone",
data: JSON.stringify(data),
processData: false,
type: 'POST',
contentType: 'application/json'
}
)
}else{
//no document if no read in
console.log("error--> " + data.errorMessage)
}
}
})
return XHR;
}
The problem is that you're using "this" in your setTimeout call. You can't do this because "this" will be the global object when the timer executes the function you're trying to reference.
like others have suggested, you need to pass an actual function to your timer, not a string. then you can reference whatever function from whatever object you want.
probably, the function getRequest isn't being called. This is, as far as I think, because you are sending a string -- "this.getRequest" to the setTimeout function. As a rule of thumb, never pass string to this, pass functions. Although, it might be perfectly ok in some situations (i'd never recommend it anyway), here 'this' might be causing trouble. Use something like this:
getRequest:function() {
var fn = arguments.callee;
var XHR = $.ajax({
url: '/nextdocument',
type: 'GET',
async: true,
cache: false,
timeout: 11000,
success:function(data) {
var name = data.description;
var price = data.price;
console.log("read--> " + name + price);
setTimeout(fn, 1000);
if (data.ok == "true") {
data["ok"] = data.ok;
$.ajax(
{
url: "/customerdone",
data: JSON.stringify(data),
processData: false,
type: 'POST',
contentType: 'application/json'
}
)
}else{
//no document if no read in
console.log("error--> " + data.errorMessage)
}
}
})
return XHR;
}

get response from FB Api JavaScript

i try to get a function return in combination with facebook api reqeust.
var g_ret = true;
function uploadImagesFbCounter(anz){
var gid='';
$("div[id ^= 'gallerydetail']").each(function (i) {
gid = this.id.split('-');
gid = parseInt(gid[1]);
})
if(gid==0) return true;
FB.api('/me', function(response) {
  //console.log(response);
  var uid = response.id;
if(!anz){
g_ret = $.ajax({
type: "POST",
async:false,
url: "api/gallerie_anz_speich.php",
data: "uid="+uid+"&op=get&gid="+gid
});
if(g_ret.response >= 20) {
g_ret = false;
}
} else {
g_ret = $.ajax({
type: "POST",
async:false,
url: "api/gallerie_anz_speich.php",
data: "uid="+uid+"&op=set&gid="+gid
});
//console.log(g_ret.response);
g_ret = '<span style="padding:0 5px;">Noch '+(20-g_ret.response)+'Fotos</span>';
console.log(g_ret);
}
});
return g_ret;
}
what ever I do, i get an empty response.... please help!
The API you're using is asynchronous. You can't return a value from your function like that; it's just impossible in such a situation.
Instead, write your API so that its clients pass it a callable function. Inside the Facebook API callback, you can call that function and pass it that "g_ret" string.
function uploadImagesFbCounter(anz, callback){
// ...
FB.api('/me', function(response) {
// ...
callback(g_ret);
});
}
Then when you call your function, instead of:
var result = uploadImagesFbCounter( whatever );
// ... do something with result ...
you'd do this:
uploadImagesFbCounter( whatever, function( result ) {
// ... do something with result ...
});
Getting the user information from Facebook's servers is asynchronous. This means, any code you write after FB.api() does not wait for Facebook to respond. Your browser is not blocked just to wait for Facebook's servers. This is the same concept as AJAX, which I believe you are familiar with because I see you use it in your code.
The common way to "get a return value" from an asynchronous server request is to use a callback function.
function uploadImagesFbCounter(anz, onSuccess){
var gid='';
$("div[id ^= 'gallerydetail']").each(function (i) {
gid = this.id.split('-');
gid = parseInt(gid[1]);
})
if(gid==0) return true;
FB.api('/me', function(response) {
//console.log(response);
var uid = response.id;
if(!anz){
g_ret = $.ajax({
type: "POST",
async:false,
url: "api/gallerie_anz_speich.php",
data: "uid="+uid+"&op=get&gid="+gid
});
if(g_ret.response >= 20) {
g_ret = false;
}
} else {
g_ret = $.ajax({
type: "POST",
async:false,
url: "api/gallerie_anz_speich.php",
data: "uid="+uid+"&op=set&gid="+gid
});
//console.log(g_ret.response);
g_ret = '<span style="padding:0 5px;">Noch '+(20-g_ret.response)+'Fotos</span>';
console.log(g_ret);
}
onSuccess(g_ret);
});
}
uploadImagesFbCounter(
whateverAnzIs,
function(g_ret) {
console.info(g_ret);
}
);

Categories