This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I have the following variables ready to hold strings that are returned from the API call:
// Variables for the Twitch user's object
var tName = "tName";
var tLogo = "tLogo";
var tGame = "tGame";
var tChannel = "tChannel";
Then I have this function which holds an AJAX call:
function twitchInfo(user){
$.ajax({
url: streams + user,
success: function(response){
if (response.stream){
tName = response.stream.channel.display_name;
tLogo = response.stream.channel.logo;
tGame = response.stream.game;
tChannel = response.stream.channel.status;
} else {
$.ajax({
url: users + user,
success: function(data){
tName = data.display_name;
if (data.logo) {
tLogo = data.logo} else {tLogo = defLogo}
tGame = "Offline";
tChannel = " ";
}
})
};
}
})
};
The function is being called from a loop that iterates through an array of users.
I checked the call URL's and they all return data just fine.
I wanted that data from the ajax call(s) to update the variables, but on investigating by doing a console.log(tName + tLogo ....), nothing is being updated.
Can anyone spot why? Any thoughts would be appreciated.
Thanks
edit
$(document).ready(function() {
//the Twitch accounts to include:
var twitchUsers = ["OgamingSC2", "ESL_SC2", "FreeCodeCamp", "storbeck", "brunofin", "comster404", "lastUser"];
var defLogo = "https://cdn1.iconfinder.com/data/icons/user-experience/512/user-unknown-512.png";
//Beginning of API call
var streams = "https://api.twitch.tv/kraken/streams/";
var users = "https://api.twitch.tv/kraken/users/";
//Twitch user's object which will hold the info from the API calls.
var AccInfo= {};
// Variables for the Twitch user's object
var tName = "tName";
var tLogo = "tLogo";
var tGame = "tGame";
var tChannel = "tChannel";
//Object constructor
function twitchUser(name, logo, game, channel){
this.name = name;
this.logo = logo;
this.game = game;
this.channel = channel;
}
function twitchInfo(user){
$.ajax({
url: streams + user,
success: function(response){
if (response.stream){
tName = response.stream.channel.display_name;
tLogo = response.stream.channel.logo;
tGame = response.stream.game;
tChannel = response.stream.channel.status;
} else {
$.ajax({
url: users + user,
success: function(data){
tName = data.display_name;
if (data.logo) {
tLogo = data.logo} else {tLogo = defLogo}
tGame = "Offline";
tChannel = " ";
}
})
};
}
})
};
for (p=0; p<twitchUsers.length; p++){
twitchInfo(twitchUsers[p]);
$("#theTable").append("<tr><td class=\"theLogo\"><img src=" + AccInfo.logo + "></td><td class=\"user\"><a href=\"http://www.twitch.tv/" + AccInfo.name + "\">"+ AccInfo.name +"</td><td>"+ AccInfo.game + " " + AccInfo.channel + "</td></tr>");
console.log(twitchUsers[p] + " " + tName + " " + tLogo + " " + tGame + " " + tChannel + " ");
}
});
Where are those variables declared?
Maybe they are out of scope. Can you provide a more complete sample?
You could also try to pass a callback to your twitchInfo function. So, instead of updating the variables within the method, you just assign the callback to the success attribute:
function twitchInfo(user, callback){
$.ajax({
url: streams + user,
success: callback
})
};
and when you call the function, just create an inline function making sure the variables that you want to update are in scope:
twitchInfo("some user", function(response) {
if (response.stream){
tName = response.stream.channel.display_name;
tLogo = response.stream.channel.logo;
tGame = response.stream.game;
tChannel = response.stream.channel.status;
} else {
$.ajax({
url: users + user,
success: function(data){
tName = data.display_name;
if (data.logo) {
tLogo = data.logo} else {tLogo = defLogo}
tGame = "Offline";
tChannel = " ";
}
})
}
);
Related
I have this "click Listener" that calls and sends a userId parameter to the function-"getModalData" which then returns an array value to the variable-"arrayedUserData".
$('body').on('click', '.openModal', function () {
var userId = $(this).val(),
btnText = $(this).text(),
btnClass = '',
colorCode = '',
arrayedUserData = getModalData(userId);
if (btnText === "Delete") {
btnClass = 'danger';
colorCode = '#d9534f';
} else {
btnClass = 'warning';
colorCode = '#f0ad4e';
}
$('#actionBtn').removeClass().addClass('btn btn-' + btnClass).text(btnText);
$('#modalTitle').text('Confirm ' + btnText);
$('#S-modalbody p').text('Are you sure you want to ' + btnText + ' user: ');
$('#S-modalbody h4').css('color', colorCode).text(userId + " - " + arrayedUserData.LastName + ", " + arrayedUserData.FirstName);
});
This is the function-"getModalData". The returned php array from the Ajax's "success" will then be passed to the variable-"UserData" that is then returned by the function.
function getModalData(passedUserId) {
var UserData;
$.ajax(
{
type: "POST",
url: "get/get_modal_data.php",
data: { passedUserId: passedUserId },
dataType: "json",
success: function (data) {
UserData = data;
}
}
);
return UserData;
}
this is the "get_modal_data.php".
<?php
include "../includes/connect.php";
if (isset($_POST['passedUserId'])) {
$UserId = mysqli_real_escape_string($con, $_POST['passedUserId']);
$getUserData = mysqli_query($con, "SELECT * FROM tblUserAccounts WHERE uaUserId = '".$UserId."'");
$uaRow = mysqli_fetch_assoc($getUserData);
$UserDataArr = array("UserId" => $uaRow['uaUserId'],
"EmailAddress" => $uaRow['uaEmailAddress'],
"FirstName" => $uaRow['uaFirstName'],
"LastName" => $uaRow['uaLastName'],
"BirthDate" => $uaRow['uaBirthDate'],
"Address" => $uaRow['uaAddress'],
"Gender" => $uaRow['uaGender'],
"ContactNumber" => $uaRow['uaContactNumber'],
"BloodTypeId" => $uaRow['uaBloodTypeId'],
"AccountStatus" => $uaRow['uaAccountStatus'],
);
echo json_encode($UserDataArr);
exit();
}
?>
this error appears on the console:
Uncaught TypeError: Cannot read property 'LastName' of undefined get_user_accounts.js:66
this is the line 66 of get_user_accounts.js, which is present on the "click listener".
$('#S-modalbody h4').css('color', colorCode).text(userId + " - " + arrayedUserData.LastName + ", " + arrayedUserData.FirstName);
but, I am confused because the php array appears on the browser's Network Response:
Successful Connection{"UserId":"1","EmailAddress":"paulanselmendoza#gmail.com","FirstName":"Paul Ansel","LastName":"Mendoza","BirthDate":"1998-12-17","Address":"Phase 1B Block 8 Lot 20 Olivarez Homes South, Sto. Tomas, Binan City, Laguna","Gender":"Male","ContactNumber":"2147483647","BloodTypeId":"0","AccountStatus":"ACTIVE"}
Did you see that you get: Successful Connection before the JSON data? You have to remove that, if not it will be an invalid JSON response. The code you have shared doesn't have the particular stuff.
I believe you have to check your database connection, where on successful connection, it is set to output Successful Connection, which breaks your response. Please remove that bit of code.
include "../includes/connect.php";
It can be something like:
$conn = mysqli_connect() or die("Error");
echo "Successful Connection";
Because getModalData fucntion return the UserData before it asign by ajax(UserData = data;). use a callback function:
using callbacks
function getModalData(passedUserId,callback) {
$.ajax(
{
type: "POST",
url: "get/get_modal_data.php",
data: { passedUserId: passedUserId },
dataType: "json",
success: function (data) {
callback(data);
}
}
);
}
$('body').on('click', '.openModal', function () {
var userId = $(this).val(),
btnText = $(this).text(),
btnClass = '',
colorCode = '';
getModalData(userId, function (arrayedUserData) {
if (btnText === "Delete") {
btnClass = 'danger';
colorCode = '#d9534f';
} else {
btnClass = 'warning';
colorCode = '#f0ad4e';
}
$('#actionBtn').removeClass().addClass('btn btn-' + btnClass).text(btnText);
$('#modalTitle').text('Confirm ' + btnText);
$('#S-modalbody p').text('Are you sure you want to ' + btnText + ' user: ');
$('#S-modalbody h4').css('color', colorCode).text(userId + " - " + arrayedUserData.LastName + ", " + arrayedUserData.FirstName);
});
});
Right now I have username and password saved in cookies. My goal is to send that data to my server and then the server will send back response and I will display the response on my webpage. But before I do that I used alert() to see if it is working.
I think something is wrong with the JS:
$(document).ready(function () {
var messageType = "3";
var cookie_name = "username";
var cookie_name2 = "password";
var YouWrote = getName(cookie_name);
var YouWrote2 = getName2(cookie_name2);
var userName = YouWrote;
var password = YouWrote2;
auth(messageType, userName, password);
});
function auth(messageType, userName, password) {
$.ajax({
type: "POST",
//SEND TO SERVER URL
url: "######",
dataType: 'json',
async: false,
data: '{"messageType": "' + messageType + '", "userName": "' + userName + '", "password" : "' + password + '"}',
error: function (xhr, error) {
alert('Error!');
},
success: function (data, textStatus, jqXHR) {
alert(data.details + '\nHello ' + data.clientInfo.firstName + ' ' + data.clientInfo.lastName + '. \nBalance:' + data.clientInfo.balance);
}
})
}
These two functions will help me get the cookie data saved (this works, I have tested it):
function getName() {
if (document.cookie) {
index = document.cookie.indexOf(cookie_name);
if (index != -1) {
namestart = (document.cookie.indexOf("=", index) + 1);
nameend = document.cookie.indexOf(";", index);
if (nameend == -1) {
nameend = document.cookie.length;
}
YouWrote = document.cookie.substring(namestart, nameend);
return YouWrote;
}
}
}
function getName2() {
if (document.cookie) {
index = document.cookie.indexOf(cookie_name2);
if (index != -1) {
namestart = (document.cookie.indexOf("=", index) + 1);
nameend = document.cookie.indexOf(";", index);
if (nameend == -1) {
nameend = document.cookie.length;
}
YouWrote2 = document.cookie.substring(namestart, nameend);
return YouWrote2;
}
}
}
I turned my server off on purpose because I want to see if it will show alert("Error!"). It doesn't which means the functions aren't running properly in the document.ready.
Is there an obvious issue that I'm missing? Any help will be much appreciated.
Your functions will need to have input argument specified:
function getName(cookie_name){ ... };
function getName2(cookie_name2){ ... };
In the following script, although the two weather objects are both populated with data in the ajax calls, the updateWeather call shows them both as undefined prior to that line executing. I moved the variable declarations so they would be global but they still both show undefined prior to the updateWeather call. What am I missing? Can I not set up a variable in the ajax success function and then pass it later?
Note: If you want to test this use a different url as this one won't work for you with out my credentials
function getWeatherForecastStationCode() {
var d = new Date();
var parts = d.toString().split(" ");
var dDate = parts[1] + " " + parts[2] + ", " + parts[3];
var ampm;
if (parts[4].split(":")[0] <= 12) {
ampm = "AM";
} else {
ampm = "PM";
}
var dtime = parts[4].split(":")[0] + ":" + parts[4].split(":")[1];
var datetime = dDate + " " + dtime + ampm;
alert(datetime);
var weatherStation = "KPBI"; // get from GetWeatherService.svc
var forecastFields = "&fields=periods.maxTempF%2cperiods.minTempF%2cperiods.vaildTime%2cperiods.weather%2cperiods.icon";
var currentFields = "&fields=ob.tempC%2cob.tempF%2cob.icon%2cplace.name%2cplace.state";
var forecastUrlWeatherStation = 'http://api.aerisapi.com/forecasts/' + weatherStation + '?limit=1&client_id=' + AerisClientId + '&client_secret=' + AerisWeatherApiSecret + forecastFields;
var currentUrlWeatherStation = 'http://api.aerisapi.com/observations/' + weatherStation + '?limit=1&client_id=' + AerisClientId + '&client_secret=' + AerisWeatherApiSecret + currentFields;
$.ajax({
type: "GET",
url: forecastUrlWeatherStation,
dataType: "json",
success: function (json) {
if (json.success === true) {
forecastedWeather = {
weather: json.response[0].periods[0].weather,
maxTemp: json.response[0].periods[0].maxTempF,
minTemp: json.response[0].periods[0].minTempF,
weatherIcon: json.response[0].periods[0].icon,
obsTime: datetime
};
}
else {
alert('An error occurred: ' + json.error.description);
}
}
});
var location;
$.ajax({
type: "GET",
url: currentUrlWeatherStation,
dataType: "json",
success: function (json) {
if (json.success === true) {
var place = json.response.place.name.split(" ");
if (place.length === 1) {
location = place[0].charAt(0).toUpperCase() + place[0].substr(1, place[0].length);
} else {
location = place[0].charAt(0).toUpperCase() + place[0].substr(1, place[0].length) + " " + place[1].charAt(0).toUpperCase() + place[1].substr(1, place[1].length) + ", " + json.response.place.state.toUpperCase();
}
currentWeather = {
location: location,
currentTemp: json.response.ob.tempF
};
} else {
alert('An error occurred: ' + json.error.description);
}
}
});
updateWeather(forecastedWeather,currentWeather);
}
The problem is that AJAX is Asynchronous (Thats the "A" in "AJAX"), so the call to updateWeather is executing before a response is received from your 2 ajax calls.
The way to do this then, is to wait for all ajax calls to complete before calling updateWeather.
Something like the following (untested):
$.when(getForecast(),getCurrent()).done(function(f,c){
updateWeather(forecastedWeather,currentWeather)
});
function getForecast(){
return $.ajax({
type: "GET",
url: forecastUrlWeatherStation,
dataType: "json"
....
});
};
function getCurrent(){
return $.ajax({
type: "GET",
url: currentUrlWeatherStation,
dataType: "json"
....
});
};
Hi I am getting an error while implementing the following.
When I click on the "save" button in following code:
<td width="20%"> <input id="save" onClick="updateMouseInfo();" type="button" value="Save" /></td>
I want to call the mouse_id parameter from getMouseInfo() function to updateMouseInfo() and I am getting the error that mouse_id is undefined, so please help me with the solution.
function getMouseInfo(mouse_id)
{
var dataString = {auth_token: sessionStorage.auth_token, id: mouse_id};
var mh_url = MH_HOST + '/mice/get_mouse_info.json';
alert("Inside Mouse Get Info");
$.ajax(
{
type: "POST",
url: mh_url,
data: dataString,
dataType: "json",
success: function (data)
{
//for (var info_count = 0, info_len = data.length; info_count < info_len; info_count++ );
//{
alert("Inside for loop");
//var mouse_info = data.cage.mice[info_count];
var ear_tag = document.getElementById("ear_tag");
var age = document.getElementById("age");
var genotype = document.getElementById("genotype");
var owner = document.getElementById("owner");
//var born = document.getElementById("born");
//var euthanize = document.getElementById("euthanize");
//var note = document.getElementById("note");
ear_tag.innerHTML = data[0].ear_tag;
age.innerHTML = data[0].age;
genotype.innerHTML = data[0].genotype_id;
owner.innerHTML = data[0].owner_id;
//born.innerHTML = data[0].dob;
//euthanize.innerHTML = data[0].dob;
//note.innerHTML = data[0].dob;
//}
},
error: function (data)
{
alert("fail");
}
});
}
//update mouse info
function updateMouseInfo(mouseid)
{
var ear_tag = $('#input_ear_tag').val();
var age = $('#input_age').val();
var genotype = $('#input_genotype').val();
var owner = $('#input_owner').val();
var dataString = {auth_token: sessionStorage.auth_token, id: mouseid, mouse:
{ear_tag: ear_tag, age: age,}};
var mh_url = MH_HOST + '/mice/update.json';
alert("Inside Mouse update Info");
console.log('Data String='+ dataString.auth_token + 'Mouse id=' + dataString.id);
$.ajax(
{
type: "POST",
url: mh_url,
data: dataString,
dataType: "json",
success: function (data)
{
document.getElementById('ear_tag').innerHTML = "<div" + ear_tag + "'>" + ear_tag + "</div>";
document.getElementById('age').innerHTML = "<div" + age + "'>" + age + "</div>";
document.getElementById('genotype').innerHTML = "<div" + genotype + "'>" + genotype + "</div>";
document.getElementById('owner').innerHTML = "<div" + owner + "'>" + owner + "</div>";
},
error: function (data)
{
alert("fail");
}
});
}
I am getting the following error in the browser console.
m_id=99
Data String=pvHxzkr3cys1gEVJRpCDMouse id=undefined
Whereas the id should be 99 in the above case it is showing undefined.
You are calling the updateMouseInfo function in the following manner:
onClick="updateMouseInfo();"
if you want to have same mouseid value which is taken by getMouseInfo() function when you call updateMouseInfo(),you will have to globalize getMouseInfo()
Hope it works.
I've been trying to get this right for quite some time, I'm trying to append the object from the first ajax call after the second ajax call. But the for loop seems to iterate the changing of the value to the last result before appending the information, having the last post appended every time.
var scribjson =
{
"user_id" : localStorage.viewing,
};
scribjs = JSON.stringify(scribjson);
var scrib = {json:scribjs};
$.ajax({
type: "POST",
url: "getScribbles.php",
data: scrib,
success: function(result)
{
var obj = jQuery.parseJSON(result);
for(var i = 0; i < obj.length; i+=1)
{
var userjson =
{
"user_id" : obj[i].user_id
};
userjs = JSON.stringify(userjson);
var user = {json:userjs};
localStorage.post = obj[i].post;
$.ajax({
type: "POST",
url: "getRequestsInfo.php",
data: user,
success: function(result)
{
var obj2 = jQuery.parseJSON(result);
$('#listOfScribbles').append("<tr><td><img id = 'small_pic' src = '" + obj2[0].profileImage + "'/></td><tr><td>" + obj2[0].firstname + " " + obj2[0].lastname + "</td></tr> ");
$('#listOfScribbles').append("<tr><td>" + obj[i].post + "</td></tr>");
},
error: function()
{
alert('An Error has occured, please try again.');
}
});
}
},
error: function()
{
alert('An Error has occured, please try again.');
}
});
Since ajax calls It looks like the all success functions of the inner ajax call are being called after the loop has ended, so i will always be the last iterated value.
Try this:
(function(i)
{
$.ajax({
type: "POST",
url: "getRequestsInfo.php",
data: user,
success: function(result)
{
var obj2 = jQuery.parseJSON(result);
$('#listOfScribbles').append("<tr><td><img id = 'small_pic' src = '" + obj2[0].profileImage + "'/></td><tr><td>" + obj2[0].firstname + " " + obj2[0].lastname + "</td></tr> ");
$('#listOfScribbles').append("<tr><td>" + obj[i].post + "</td></tr>");
},
error: function()
{
alert('An Error has occured, please try again.');
}
});
})(i);
This will create a closure on i, which will give each ajax call its own copy of the current value.
Use an IIFE:
success: (function(i){return function(result) {
var obj2 = jQuery.parseJSON(result);
$('#listOfScribbles').append("<tr><td><img id = 'small_pic' src = '" + obj2[0].profileImage + "'/></td><tr><td>" + obj2[0].firstname + " " + obj2[0].lastname + "</td></tr> ");
$('#listOfScribbles').append("<tr><td>" + obj[i].post + "</td></tr>");
}})(i),
etc. Currently your loop generated ajax success handlers contain a direct reference to the counter itself, which (by the time they are called) has reached its final value.