Use of global variable with ajax - javascript

Currently I am working on a website which uses asp.net and c#. I am getting data from the database using a web service and I get the correct data without an issue. However once I get the data via ajax call I need to assign it to a global variable which I later use to create a tree graph. This is where my problem comes, I've tried to assign the JSON object but I can't seem to get it to work. I keep getting an error
TypeError: treeData is undefined
Can someone guide me please. Below is the relevant code
Ajax Call
$(function () {
$.ajax({
type: "POST",
url: "MyService.asmx/SomeFunction",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: successHandler
});
});
SuccessHandler
function successHandler(data) {
var a = JSON.parse(data.d);
var b = [JSON.stringify(a)];
}
var treeData = successHandler[0]; //This part keeps giving me error
Thanks in advance for all your help and support.

You are trying to access successHandler as an array, when it is a function. You cannot use it like that. Instead, assign the [JSON.stringify(a)] to a global variable, and access that variable when you need the data, like so:
var dataFromAjax;
var treeData;
function successHandler(data) {
var a = JSON.parse(data.d);
dataFromAjax = [JSON.stringify(a)];
setTreeData();
}
function setTreeData() { //this function can be in the seperate script tag
treeData = dataFromAjax[0];
}

In this case you need to return the object from the function and use it like this successHandler()[0];
function successHandler(data) {
var a = JSON.parse('[{"a":1, "b":2}]');
return a; // you need to return the data from here.
}
var treeData = successHandler()[0]; //This part keeps giving me error
console.log(treeData)

Related

Using AJAX to get dynamic data for Materialize autocomplete

​i've been struggling with this problem for the past 3 days or so and i'm wondering if anyone could help me with this. i have a form that has a textbox using autocomplete. what i want is to have the textbox get the data from an AJAX function and not just static data.
Based on the Materialize documentation, the way to get static data is by passing an object as the second argument upon initialization of an autocomplete instance:
let elem = document.querySelector('#brand');
let instance = M.Autocomplete.init(elem, { data: { "Apple": null, "Microsoft":null} });
​
Now since i want to use AJAX for dynamic data, i made an AJAX function and also another function to pass the data from the AJAX function to after success (this is to bypass the problem with using asyncronous functions), like so:
function ajaxCall() {
$.ajax({
type: 'GET',
url: 'showBrands',
dataType: 'json',
success: passData
});
}
function passData(data) {
return data;
}
After which, i tried to do the following but no luck though.
let elem = document.querySelector('#brand');
let instance = M.Autocomplete.init(elem, { data: ajaxCall() });
Am i doing something wrong here? Or is there a better approach? Any help is greatly appreciated. thanks in advance!
Try put your materialize plugin inside passdata function:
function ajaxCall() {
$.ajax({
type: 'GET',
url: 'showBrands',
dataType: 'json',
success: passData
});
}
function passData(data1) {
let elem = document.querySelector('#brand');
var instance = M.Autocomplete.getInstance(elem);
if (instance===null || instance===undefined){
instance = M.Autocomplete.init(elem, { data: data1 });
}else{
instance.updateData(data1);
}
}

Pass function reference to a separate Javascript file for callback

I have created a common Javascript file for all my ajax calls. I am trying to use this as a common way to keep track of all ajax calls. Below is the code for the same.
function doAjax(doAjax_params) {
var url = doAjax_params['url'];
var requestType = doAjax_params['requestType'];
var contentType = doAjax_params['contentType'];
var dataType = doAjax_params['dataType'];
var data = doAjax_params['data'];
var beforeSendCallbackFunction = doAjax_params['beforeSendCallbackFunction'];
var successCallbackFunction = doAjax_params['successCallbackFunction'];
var completeCallbackFunction = doAjax_params['completeCallbackFunction'];
var errorCallBackFunction = doAjax_params['errorCallBackFunction'];
//Make the ajax call
$.ajax({
url: getBaseURL() + url,
crossDomain: true,
type: requestType,
contentType: contentType,
dataType: dataType,
data: data,
success: function (data, textStatus, jqXHR) {
console.log(typeof successCallbackFunction);
debugger
//if (typeof successCallbackFunction === "function") {
successCallbackFunction(data);
//}
},
error: function (jqXHR, textStatus, errorThrown) {
if (typeof errorCallBackFunction === "function") {
errorCallBackFunction(errorThrown);
}
}
});
}
This code takes a list of parameters and creates an ajax request based on the parameteres. This code is saved in a file APIHandler.js.
I am trying to call this function from multiple files. An example call is below.
function RedirectToDashboard() {
var params = $.extend({}, doAjax_params_default);
params['url'] = `profile/5`;
params['successCallbackFunction'] = `testsuccess`
doAjax(params);
}
function testsuccess() {
alert("success");
}
When I run this function, I am able to make the call successfully. The only issue comes with the reference to callback function. console.log(typeof successCallbackFunction); returns string instead of function.
I thought maybe order of JS made a difference. I am loading APIHandler.js and then the page specific js. And this ajax call happens at button click, so both JS files are loaded before the ajax call is made.
Other than that, I think maybe I am sending the parameters wrong. That might be causing JS to consider function name as string. But I checked most of the google suggestions on how to pass function, and it seems it needs just the name.
Is there anything else that I might be missing here?
Damn it. I just figured out why it was causing the error. I used quotes when assigning the callback function. Right after posting the question, I realised what was wrong.
params['successCallbackFunction'] = 'testsuccess'
is supposed to be changed to
params['successCallbackFunction'] = testsuccess

javascript, array of string as JSON

I'm having problems with passing two arrays of strings as arguments in JSON format to invoke ASMX Web Service method via jQuery's "POST".
My Web Method is:
[ScriptMethod(ResponseFormat=ResponseFormat.Json)]
public List<string> CreateCollection(string[] names, string[] lastnames)
{
this.collection = new List<string>();
for (int i = 0; i < names.Length; i++)
{
this.collection.Add(names[i] + " " + lastnames[i]);
}
return this.collection;
}
Now, the js:
function CreateArray() {
var dataS = GetJSONData(); //data in JSON format (I believe)
$.ajax({
type: "POST",
url: "http://localhost:45250/ServiceJava.asmx/CreateCollection",
data: dataS,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
//something
}
})
}
GetJSONData() is my helper method creating two arrays from column in a table. Here's the code:
function GetJSONData() {
//take names
var firstnames = $('#data_table td:nth-child(1)').map(function () {
return $(this).text();
}).get(); //["One","Two","Three"]
//take surnames
var surnames = $('#data_table td:nth-child(2)').map(function () {
return $(this).text();
}).get(); //["Surname1","Surname2","Surname3"]
//create JSON data
var dataToSend = {
names: JSON.stringify(firstnames),
lastnames: JSON.stringify(surnames)
};
return dataToSend;
}
Now, when I try to execude the code by clicking button that invokes CreateArray() I get the error:
ExceptionType: "System.ArgumentException" Message: "Incorrect first
JSON element: names."
I don't know, why is it incorrect? I've ready many posts about it and I don't know why it doesn't work, what's wrong with that dataS?
EDIT:
Here's dataToSend from debugger for
var dataToSend = {
names: firstnames,
lastnames: surnames,
};
as it's been suggested for me to do.
EDIT2:
There's something with those "" and '' as #Vijay Dev mentioned, because when I've tried to pass data as data: "{names:['Jan','Arek'],lastnames:['Karol','Basia']}", it worked.
So, stringify() is not the best choice here, is there any other method that could help me to do it fast?
Try sending like this:
function CreateArray() {
var dataS = GetJSONData(); //data in JSON format (I believe)
$.ajax({
type: "POST",
url: "http://localhost:45250/ServiceJava.asmx/CreateCollection",
data: {names: dataS.firstnames,lastnames: dataS.surnames} ,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
//something
}
})
}
This should work..
I think since you are already JSON.stringifying values for dataToSend property, jQuery might be trying to sending it as serialize data. Trying removing JSON.stringify from here:
//create JSON data
var dataToSend = {
names : firstnames,
lastnames : surnames
};
jQuery will stringify the data when this is set dataType: "json".
Good luck, have fun!
Altough, none of the answer was correct, it led me to find the correct way to do this. To make it work, I've made the following change:
//create JSON data
var dataToSend = JSON.stringify({ "names": firstnames, "lastnames": surnames });
So this is the idea proposed by #Oluwafemi, yet he suggested making Users class. Unfortunately, after that, the app wouldn't work in a way it was presented. So I guess if I wanted to pass a custom object I would need to pass it in a different way.
EDIT:
I haven't tried it yet, but I think that if I wanted to pass a custom object like this suggested by #Oluwafemi, I would need to write in a script:
var user1 = {
name: "One",
lastname:"OneOne"
}
and later pass the data as:
data = JSON.stringify({ user: user1 });
and for an array of custom object, by analogy:
data = JSON.stringify({ user: [user1, user2] });
I'll check that one later when I will have an opportunity to.

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

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