Unable to update parent functions variable from inside $.ajax call - javascript

I am trying to push a value that is being returned inside the ajax call to an array outside of the call, but still inside the parent function. It seems that I am not able to access any variable and update it from inside the ajax success statement. Thanks in advance for the help.
var bill = [];
var billDate = [];
$(document).ready(function(){
$.ajax({
url: '../Js/readData.php',
data: "",
dataType: 'json',
success: function(data)
{
//var obj=JSON.parse(data);
var obj=data;
for (var x in obj)
{
bill.push(obj[x].Amount);
billDate.push(obj[x].Dates);
}
}
});

The ajax call is asynchronous so the variables are not updated immediately for availability outside of the success function. It is called after the time involved with loading the data from the server.
You may want to move the anonymous success function to an external function and do whatever handling you need in there.
$(document).ready(function(){
$.ajax({
url: '../Js/readData.php',
data: "",
dataType: 'json',
success: mySuccessFunction
});
var mySuccessFunction = function(obj) {
for (var x in obj)
{
bill.push(obj[x].Amount);
billDate.push(obj[x].Dates);
}
}

Related

Ajax saving array into global variables not working keep getting undefined

Trying to save an array retrieved from ajax into a global variable such that I may use it later on but keep getting undefined error
<script>
var items = [];
function add(value){
items.push(value);
}
$(document).ready( function() {
$.ajax({
type: 'POST',
url: 'xxxx.php',
dataType: 'json',
cache: false,
success: function(result) {
for(i=0; i < result.length; i++){
add(result[i]);
}
},
});
});
document.write(items[1])
</script>
This is an asynchronous AJAX call. The call to add will be done at a later time than the execution of document.write(items[1]);
So this is the right way to do it:
<script>
var items = [];
function add(value){
items.push(value);
}
$(document).ready( function() {
$.ajax({
type: 'POST',
url: 'xxxx.php',
dataType: 'json',
cache: false,
success: function(result) {
for(i=0; i < result.length; i++){
add(result[i]);
}
document.write(items[1])
},
});
});
</script>
This way the function that uses the result, will be executed when the result function is executed.
Think it this way: you said: Here is this lemon basket. Then you asked someone to go somewhere and get the lemons and before he returned you tried to count the lemons. Got it ?
You can use ajaxstop to call the method after the ajax request has completed. Place the following function in document ready:
$(document).ajaxStop(function () {
document.write(items[1]);
});
The above solution works but this is another option I used when waiting for multiple ajax functions to complete. This will call every time you complete an ajax request but there is a way to limit to one call if need be.

Set variables in JavaScript once function finishes

I have two functions that makes Ajax calls: getData and getMoreData. getMoreData requires a url variable that is dependent on the url variable getData. This questions continues from: String append from <select> to form new variable.
By appending an item obtained from the received from getData onto a base URL, I create a new variable (Let's call this NewDimensionURL) that I use for getMoreData url. However, NewDimensionURL will show error because the original list (from getData) has yet to be populated and will append nothing onto the base URL.
An idea that I have is to set NewDimensionalURL once getData finishes populating the combobox, so that getMoreData can run after.
JavaScript
var GetDimensions = 'SomeURL1';
//--Combines URL of GetDimensionValues with #dimensionName (the select ID)
var UrlBase = "Required URL of getMoreData";
var getElement = document.getElementById("dimensionName");
var GetDimensionValues = UrlBase + getElement.options[getElement.selectedIndex].text;
function handleResults(responseObj) {
$("#dimensionName").html(responseObj.DimensionListItem.map(function(item) {
return $('<option>').text(item.dimensionDisplayName)[0];
}));
}
function handleMoreResults (responseObj) {
$("#dimensionId").html(responseObj.DimensionValueListItem.map(function(item) {
return $('<option>').text(item.dimensionValueDisplayName)[0];
}));
}
function getData() {
debugger;
jQuery.ajax({
url: GetDimensions,
type: "GET",
dataType: "json",
async: false,
success: function (data) {
object = data;
handleResults(data);
}
});
}
function getMoreData() {
debugger;
jQuery.ajax({
url: GetDimensionValues,
type: "GET",
dataType: "json",
async: false,
success: function (data) {
object = data;
handleMoreResults (data);
}
});
}
Answered
Reordered as:
var GetDimensionValues;
function handleResults(responseObj) {
$("#dimensionName").html(responseObj.DimensionListItem.map(function(item) {
return $('<option>').text(item.dimensionDisplayName)[0];
}));
GetDimensionValues = UrlBase + getElement.options[getElement.selectedIndex].text;
}
Created onchange function Repopulate() for getMoreData() to parse and for handleMoreResults() to populate.
I'm guessing you just do getData(); getMoreData() back to back? If so, then you're running getmoreData BEFORE getData has ever gotten a response back from the server.
You'll have to chain the functions, so that getMoreData only gets executed when getData gets a response. e.g.
$.ajax($url, {
success: function(data) {
getMoreData(); // call this when the original ajax call gets a response.
}
});
Without seeing your code it's hard to say if this is the right solution, but you should try chaining the functions:
$.ajax({url: yourUrl}).then(function (data) {
// deal with the response, do another ajax call here
}).then(function () {
// or do something here
});

wait for ajax result to bind knockout model

I have getGeneral function that calls ajax GET. When ajax recieves data (json), it creates KO model from given json and returns created KO.
When Knockout model is created and values are assigned, knockout applybindings should be called. Here is my code:
Defines GeneralModel and some related functions (inside "GeneralModel.js"):
var GeneralModel = function() {
//for now it is empty as data ar binded automatically from json
// CountryName is one of the properties that is returned with json
}
function getGeneral(pid) {
$.ajax({
url: "/api/general",
contentType: "text/json",
dataType: "json",
type: "GET",
data: { id: pid},
success: function (item) {
var p = new GeneralModel();
p = ko.mapping.fromJS(item);
return p;
},
error: function (data) {
}
});
}
This is called from another file (GeneralTabl.html), it should call get function and applyBindings to update UI:
var PortfolioGeneral = getGeneral("#Model.Id");
ko.applyBindings(PortfolioGeneral, document.getElementById("pv-portfolio-general-tab"));
However, in this scenario I am getting error (CountryName is not defined). This is because applyBindings happens before ajax returns data, so I am doing applyBindings to empty model with undefined properties.
Mapping from Json to Model happens here and is assignes values:
p = ko.mapping.fromJS(item);
I can also fill in GeneralModel with all fields, but it is not necessary (I guess):
var GeneralModel = function() {
CountryName = ko.observable();
...
}
It will still give an error "CountryName is not defined".
What is the solution?
1) Can I somehow move getGeneral inside GeneralModel, so get data would be part of GeneralModel initialization?
or
2) Maybe I should somehow do "wait for ajax results" and only then applyBindings?
or
I believe there are other options, I am just not so familiar with KO and pure JS.
Note: I fully understand that this is because Ajax is Async call, so the question is how to restructure this code taking into account that I have two seperate files and I need to call getGeneral from outside and it should return some variable.
Try using the returned promise interface:
function getGeneral(pid) {
return $.ajax({
url: "/api/general",
contentType: "text/json",
dataType: "json",
type: "GET",
data: {
id: pid
}
});
}
getGeneral("#Model.Id").done(function (item) {
var p = new GeneralModel();
p = ko.mapping.fromJS(item);
ko.applyBindings(p, document.getElementById("pv-portfolio-general-tab"));
}).fail(function () {
//handle error here
});

scope of var in jquery function? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does Asynchronous means in Ajax?
why my var "temp" is 0 after the ajax?
function calc7() {
var temp = 0;
$.ajax({
type: "POST",
url: 'Helpers/CalcResult7.ashx',
data: { GU_ID: '<%=Request.QueryString["GUID"] %>' },
success: function (data) {
list1 = eval(data);
temp = parseFloat(myJSONObject.bindings[0].value);
$("#<%=ProResult7.GetSpanId %>").text(addCommas(temp));
}
});
return temp;
}
Because the ajax call is asynchronous, so temp is returned before being updated ...
Because the success function doesn't run until the HTTP response is comes back from the server.
Ajax is asynchronous.
Do what you want to do with the data in the success function (or in functions you call from it).
Don't try to wait for a response and then return data to a calling function.
Ajax calls are asynchronous but you can use CommonJS Promises/A pattern to achieve what you want. jQuery provides it's own implementation of it: jQuery.Deferred().
As others have mentioned here, because ajax is asynchronous, you're not guaranteed to get the updated temp variable before your return statement. It would be best to work within your success function. However, if you absolutely have to wait for that call to finish and return the temp variable, you can make it Non-asynchronous by adding async: false
function calc7() {
var temp = 0;
$.ajax({
type: "POST",
url: 'Helpers/CalcResult7.ashx',
data: { GU_ID: '<%=Request.QueryString["GUID"] %>' },
async: false,
success: function (data) {
list1 = eval(data);
temp = parseFloat(myJSONObject.bindings[0].value);
$("#<%=ProResult7.GetSpanId %>").text(addCommas(temp));
}
});
return temp;
}
S.ajax/$.post/$.get etc etc, all these are asynchronous process (which means, you will come out of the loop even before $.ajax is completed, even though it will be going to server side after coming out of the loop)
function calc7() {
var temp = 0;
$.ajax({
type: "POST",
.............
..............
}
});
return temp;
}
So just after the loop if you will check, the following statement might not have executed(depending upon the data set).
temp = parseFloat(myJSONObject.bindings[0].value);
so to check the data in temp variable you should put a debugger/alert inside $.ajax. example :
function calc7() {
var temp = 0;
$.ajax({
type: "POST",
url: 'Helpers/CalcResult7.ashx',
data: { GU_ID: '<%=Request.QueryString["GUID"] %>' },
success: function (data) {
list1 = eval(data);
temp = parseFloat(myJSONObject.bindings[0].value);
alert(temp);
$("#<%=ProResult7.GetSpanId %>").text(addCommas(temp));
}
});
return temp;
}
now you will get the value of temp

Javascript value is returned from webservice but will not show unless a breakpoint is used

I have a javascript function that calls a web service. The data comeback (I see the Jason return in FireBug) the value is blank when I attempt to use it unless I set a break point. With a break point set the value can be used, without it is not available.
Here is a snippet of the offending call.
function getTheNote(noteCode){
var _myNote = "";
var theID = $('#CustNo').val();
var myDTO = { 'theID': theID, 'noteCode': noteCode, };
var toPass = JSON.stringify(myDTO);
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "AR_Cust_Mgt.aspx/getNote",
data: toPass,
success: function (data) {
_myNote = data.d;
}
});
//setTimeout(_myNote += _myNote, 120000);
//for(var x = 0; x < 200000; x++){}
//return _myNote;
alert(_myNote);
}
Originally I was sending the value back to a calling function the return statement is where I would set my break point and the data would be returned, without nothing. Now you can see I attempted to use an alert inside the function with the same results.
With a break point I get a value without I get nothing, I have even attempted to use some delays.
Please help.
The ajax call is asynchronous. Anything you want to do with the result needs to be in your anonymous function success: function(data) { ... or the anonymous function needs to call other functions to do stuff.
As it is coded now, $.ajax will be called, the script execution continues on before the ajax call returns.
small change, big difference: you are not calling alert IN the succes function
success: function (data) {
_myNote = data.d;
alert(_myNote);
}

Categories

Resources