populated jquery objects show as undefined when passed - javascript

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

Related

Why is this jQuery ajax button click event firing multiple times in MVC4 C#.net?

I am working on a MVC4 C#.Net project and when I am trying to
click the button ('#btn_rightArw_Dwn') then the ajax call fires multiple times in MVC4. Why this is happening? Please look up on below jQuery code.
Below I have added jQuery code.
$("#btn_rightArw_Dwn").click(function() {
$('.fade_bg').show();
var Masterid = $('#MastersId').val();
var pgm_id = $('#program1').val();
if ($('#rdclick').val() == "0") {
$.ajax({
url: "/DataInput/Arrow_Load_Down?Id=" + Masterid + "&flag=" + "Right" + "&type=" + 0 + "&pgm_id=" + pgm_id,
async: true,
data: {},
success: function(data) {
$('#DVmaster').html(data);
$('#btn_rightArw1').attr('hidden', false);
$('#btn_LeftArw1').attr('hidden', false);
var production_id = $('#program1').val();
$.ajax({
url: "/DataInput/Arrow_Load_Details_Down?Id=" + Masterid + "&flag=" + "Right" + "&ProductnSts_id=" + pgm_id + "&type=" + 0,
async: false,
data: {},
success: function(data) {
$('#DVDetails').html(data);
$('#DVDetails').show();
$('#btn_rightArw_Dwn').attr('hidden', false);
$('#btn_LeftArw_dwn').attr('hidden', false);
},
error: function(html) {
$('.fade_bg').hide();
}
});
var channelid = $("#channel1").val();
var starttime = $("#StartTime").val();
var Endtime = $("#EndTime").val();
var date = $("#Date").val();
var Vimpact = $("#Viewers").val();
var gradeid = $("#grade1").val();
var seclength = $("#Seconds option:selected").text();
var Daypartid = $('#daypartid').val();
var itemid = $('#item1 option:selected').val();
var brandid = $("#brand1 option:selected").val();
$.ajax({
url: "/DataInput/Print_Labels_in_Edit?starttime=" + starttime + "&finishtime=" + Endtime + "&date=" + date + "&channelid=" + channelid + "&impact1=" + Vimpact + "&Seclength=" + seclength + "&gradesid=" + gradeid + "&itemid=" + itemid + "&brandid=" + brandid,
cache: false,
success: function(html) {
var labels = html.split(',');
var daypartname = labels[0];
var CPH = labels[1];
var TVR = labels[2];
var Mediavalue = labels[3];
var daypartid = labels[4];
$('.fade_bg').hide();
$('#lblDaypart').text(" " + daypartname);
$("#lblCPH").text('£' + " " + CPH);
$('#lblTvr').text(" " + TVR);
$('#lblMediaValue').text(" " + "£ " + Mediavalue);
$('#daypartid').val(daypartid);
},
error: function(html) {
$('.fade_bg').hide();
}
});
}
});
}
});
Thanks in advance.

Why aren's these AJAX calls updating my variables? [duplicate]

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

object doesn't support this property or method using AJAX

Please see the code below:
$.ajax({
type: "POST",
url: "Results1.aspx/TableQuery",
data: JSON.stringify({
mappingid: res[i],
strCon: $("#fieldGenieConnectionString")[0].value,
strTypeSession: $("#fieldTypeSession")[0].value
}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess(i, res.length),
error: OnError,
failure: function (response) {
alert('there was a failure loading the webpage')
}
});
and the code below:
function OnSuccess(i, totalrows) {
return function (response) {
//if (response.d != "") {
var strResponse = response.d;
strResponse = strResponse.toUpperCase;
if (strResponse.indexOf("<TR>") > 0) {
// alert(response.d);
document.getElementById('div' + i).innerHTML = document.getElementById('div' + i).innerHTML + '<br>' + '<br>' + response.d;
}
numSucceeded++;
var completeCalculation = (numSucceeded / totalrows) * 100
var rounded = completeCalculation.toFixed(0);
document.getElementById('ProgressIndicator').innerHTML = rounded + ' % complete';
document.getElementById('ProgressIndicator2').innerHTML = rounded + ' % complete';
if (numSucceeded === totalrows) {
var end = new Date().getTime();
var htmlResponse = "Loaded after: " + (end - start) / 1000 + " seconds"
document.getElementById('TotalTimeLabel').innerHTML = htmlResponse;
document.getElementById('TotalTime2Label').innerHTML = htmlResponse;
$("#LoadingImage").hide();
$("#LoadingImage2").hide();
}
}
}
The following line causes an error:
if (strResponse.indexOf("<TR>") > 0) {
strResponse = strResponse.toUpperCase;
There is a typo here. I think you want to write strResponse = strResponse.toUpperCase();
You are assigning a function to strResponse instead of calling the toUpperCase() on the existing strResponse

AJAX call data returned from mvc function is undefined

I know this has been asked 1000 times before but I have hit a brick wall with this.^have created a web application that inserts user data and feedback for the user and the code below is basically part of the PhoneGap application. The strange thing is that the code works perfectly in a web browser but not in Phonegap (output iPad via Xcode).
Therefore would someone know why I am getting an undefined error for the following AJAX call, just after the success callback and the alert(data.ResultId). , any help is appreciated.
Thank you!
// POST: /Result/Create
[HttpPost]
public ActionResult Create(Result result)
{
if (ModelState.IsValid)
{
result.ResultDate = DateTime.Now;
repository.InsertResult(result);
repository.Save();
if (Request.IsAjaxRequest())
{
int ResultId = result.ResultId;
try
{ //valid database entry..send back new ResultId
return Json(new { Success = true, ResultId, JsonRequestBehavior.AllowGet });
}
catch
{ // no database entry
return Json(new { Success = false, Message = "Error", JsonRequestBehavior.AllowGet });
}
}
return RedirectToAction("Index");
}
return View(result);
}
Insert QnA
function InsertQnA() {
//hardcoded for testing
Q1 = 10;
Q2 = 10;
Q3 = 10;
Q4 = 10;
Q5 = 10;
Q6 = 10;
Q7 = 10;
Q8 = 10;
Q9 = 10;
Q10 = 10;
localStorage.setItem("Total",100);
localStorage.setItem("CaseStudy", 1);
localStorage.setItem("UserId",1);
Attempts = "1";
////////////////
$.ajax({
url: Domain + '/Result/Create',
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: '{"Q1":"' + Q1 + '","Q2":"' + Q2 + '","Q3":"' + Q3 + '","Q4":"' + Q4 + '","Q5":"' + Q5 + '","Q6":"' + Q6 + '","Q7":"' + Q7 + '","Q8":"' + Q8 + '","Q9":"' + Q9 + '","Q10":"' + Q10 + '","Total":"' + localStorage.getItem("Total") + '","CaseStudy":"' + localStorage.getItem("CaseStudy") + '","UserId":"' + localStorage.getItem("UserId") + '","Attempts":"' + QnANumAttempts + '"}',
// dataType : "json",
success: function (data) {
alert(data.ResultId);
if (data.Success==true) {
}
else if (data.Success==false) {
viewModel.UserId("Your entry has not been saved, please try again.");
}
},
}).fail(
function (xhr, textStatus, err) {
console.log(xhr.statusText);
console.log(textStatus);
console.log(err);
});
}
The problem was that I was tying to use the same ActionResult to serve an MVC view as well as an htlm5 cordova iOS app. I got round this by copying the ActionResult but changing the return type to a string, note the code looks a bit different in the action, however the original worked fine too. Many thanks to all who posted
[HttpPost]
public string CreateResult(Result result)
{
result.ResultDate = DateTime.Now;
repository.InsertResult(result);
repository.Save();
if (result == null)
{
// User entity does not exist in db, return 0
return JsonConvert.SerializeObject(0);
}
else
{
// Success return user
return JsonConvert.SerializeObject(result, Formatting.Indented, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
}
}
AJAX
$.ajax({
url: Domain + '/Result/CreateResult',
cache: false,
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: '{"Q1":"' + Q1 + '","Q2":"' + Q2 + '","Q3":"' + Q3 + '","Q4":"' + Q4 + '","Q5":"' + Q5 + '","Q6":"' + Q6 + '","Q7":"' + Q7 + '","Q8":"' + Q8 + '","Q9":"' + Q9 + '","Q10":"' + Q10 + '","Total":"' + localStorage.getItem("Total") + '","CaseStudy":"' + localStorage.getItem("CaseStudy") + '","UserId":"' + localStorage.getItem("UserId") + '","Attempts":"' + QnANumAttempts + '"}',
success: function (data) {
try {
if (data != 0) {
//result id used for feedback insertion > update result entity
localStorage.setItem("ResultId", data.ResultId);
viewModel.UserId("You have successfully completed case study " + localStorage.getItem("CaseStudy") + ", please fill out the <a href=evaluation.html target=_self>evaluation.<a/>");
//reset locals
ResetLocalStorage();
//count number of entities for User
CountUserEntitiesInResults();
}
else
{
viewModel.UserId("Your entry has not been saved, please try again.");
}
}catch(error) {
alert("This is the error which might be: "+error.message);
}
},
}).fail(
function (xhr, textStatus, err) {
console.log(xhr.statusText);
console.log(textStatus);
console.log(err);
});​

Changing global variables in a ajax call

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.

Categories