I have a js file called example.js which has a line as follows:
gridOptions.api.setRowData(createRowData());
Then there's another file data.js which has the createRowData() function that should return ROW_DATA. It is as follows:
function createRowData() {
jQuery.getJSON('/file.txt',function(ROW_DATA){
return ROW_DATA;
});
}
But, whenever this createRowData() function is called from example.js file, it does not go inside the jQuery block and simply comes to the last curly bracket. Can anyone please tell me what is going wrong here??
I believe that you're not getting the value because getJSON is asynchronous as others have said. createRowData is retrieving the value at a later time rather than when it's called.
Here is one way to get the data with promises. I commented what's going on below:
function createRowData() {
//return a new promise
return new Promise(function(resolve, reject){
jQuery.getJSON('/file.txt',function(ROW_DATA){
//on reject, send an error
if (ROW_DATA === null) reject("Error fetching data");
//on resolve, send the row data
return resolve(ROW_DATA);
});
});
}
//use then to describe what happens after the ajax request is done
gridOptions.api.setRowData(createRowData()).then(function(rowdata){
return rowdata; //log data or error
})
Edit: to do a synchronous ajax request, you may be able to do something like this, referring to this SO question.
function createRowData() {
$.ajax({
url: "/file.txt'",
async: false,
success: function(rowdata){
return rowdata
}
})
}
To read some data to a variable like you mentioned, nodejs may help because it can handle reading input/output, and probably to a variable as well.:
You get JSON from the file, pass the result to the callback function, and then return it. Return it where??
As I said, your anonymous function is a callback one.
Program says: When you are done reading from the file, call this function, OK?.
While you do that, I am doing something else.
And that is what it does. The program, would go on, until the file is read, when your callback anonymous function would be called.
You can do sth like this.
createRowData(gridOptions.api);
// add code here if you want this code to execute even before you get the response
function createRowData(api) {
jQuery.getJSON('/file.txt',function(ROW_DATA,api){
api.setRowData(ROW_DATA);
//Whatever else you want to do. In case you want this to be done only
//after the values have been read
});
}
If you want to wait, for the file to be read, just, dont do anything after the function, but put it inside the callback function.
Related
I have two modules and in the first one I declare an object because I know that primitives are passed by value in java script and objects by reference.I want to get the response status from a request and I am passing the object as a reference so I will be able to modify its property.The problem is that it doesn't do anything.In the end the value would be the same.
//this code is in a different module from the other one
var variableToBeChanged = { something : "Initial value" };
anotherModule.changeValue(variableToBeChanged);
alert(variableToBeChanged.something);
//and in the other module I have a $.ajax and I want to get the response status(ex. 200)
//the code is sth like this:
function AnotherModule(ajax){
function changeValue(variableToBeChanged){
...
...
...
$.ajax({
...
...
...
success: function(data,xhr){
variableTobechanged.something = xhr.status;
}
});
}
}
In the end it will display: "Initial value" instead of 200 or anything else.
What am I doing wrong here?
The ajax call is asynchronous and therefore the alert gets called before the variable is modified. You can use promise in ES6 like this to make sure it is executed after ajax call completes.
new Promise((resolve) =>{
anotherModule.changeValue(variableToBeChanged);
resolve();
}).then((res) =>{
alert(variableToBeChanged.something);
}).catch((error) =>{
alert(error);
});
In javascript copy of reference to object is passed.
This means that any changes made to the object will be visible to you after the function is done executing.
Since javascript is asynchronous , alert(variableToBeChanged.something) this line gets executed before your function returns . Therefore you see old value . You have to use callbacks or promise to work synchronously.
Please refer to this question javascript pass object as reference .It explains this concept beautifully.
I want to package a ajax call into an interface without then.
If i do like this, it will just return 'No ajax return';
var ajaxReturn = ajaxFunction();
function ajaxFunction(){
var text = 'No ajax return';
// get fileName using an ajax get
$.ajax();
return text;
}
If i do like this, it will be ugly for using then;
function ajaxFunction(){
var text = 'No ajax';
var dtd = $.Deferred();
$.ajax();
return dtd.promise();
}
$.when(ajaxFunction()).then();
I just want the interface to be simple and return the right thing, can i?
//return the right
var ajaxReturn = ajaxFunction();
function ajaxFunction(){
var text = 'No ajax';
var dtd = $.Deferred();
$.ajax();
return dtd.promise();
}
$.when(ajaxFunction()).then();
Whoa, what is all that? You do need .then but you don't need most of the surrounding stuff. $.ajax generates a promise for you. You don't need to make a promise object yourself. In fact, often the only reason you need to manually set up a Deferred/Promise directly is if you're using some library that sets up callbacks and doesn't use promises itself.
function ajaxFunction(){
return $.ajax();
}
ajaxFunction().then(function(data) { ... });
Now, let's say that you didn't actually want to return the JSON structure on the end of the ajax function; you want to take out just a number from inside of it, or tweak one value to make it an easier-to-use function for its callers. Easy enough:
function ajaxFunction(){
return $.ajax().then(function(data) {
return data[12].number;
}
}
ajaxFunction().then(function(number) { ... });
In direct answer to your question: No, what you asked for isn't possible. Whenever your JavaScript methods are running, the browser can't process other events like clicks and even basic scroll operations. So, any long-running operations (like contacting the server) do not return straight away, and instead offer a callback operation.
Well..., ajax is asynchronous so you either use .then() or use a callback logic... Doing synchronous ajax is not a option for me, so I won't even mention it.
The alternative to .then() would be something like this:
ajaxFunction(function(res){ // pass a function into it
// this will be called when the ajax is done
alert(res);
});
function ajaxFunction(callback){
// get fileName using an ajax get
$.ajax({
success: callback
});
}
But again, maybe you can use just a normal ajax callback pattern anyway
$.ajax({
...
success: function(res){
// use the res
}
});
Ajax is asynchronous. then is designed to make writing async operations look more similar to synchronous code and can actually be very elegant.
Additionally, $.ajax() returns a promise and is well suited to be written as follows:
function ajaxFunction(){
return $.ajax();
}
ajaxFunction().then(function(response){
// do whatever you want with the response
})
You simply can't write asynchronous code that way (ajaxResult = ajaxFunction()). The interpreter is going to keep trucking along line by line and ajaxResult will not be ready in time.
Read up on chaining $.Deferred's. It will really clean up your async code.
I am having a problem, or perhaps a lack of understanding, with the jQuery execution order of $.get() function. I want to retrieve some information from a database server to use in the $.ready() function. As you all know, when the get returns, it passes the data to a return handler that does something with the data. In my case I want to assign some values to variables declared inside the ready handler function. But the problem is, the return handler of $.get() does not execute until after ready has exited. I was wondering if (a) am I doing this right/is there a better way or if (b) there was a way around this (that is, force the get return handler to execute immediately or some other fix I'm not aware of). I have a feeling this is some closure thing that I'm not getting about JavaScript.
As per request, I'll post an example of what I mean:
$(function() {
var userID;
$.get(uri, function(returnData) {
var parsedData = JSON.parse(returnData);
userID = parsedData.userID;
});
});
So as you can see, I'm declaring a variable in ready. Then using a get call to the database to retrieve the data needed. Then I parse the JSON that is returned and assign the userID to the variable declared before. I've tested it with a couple alerts. An alert after the get shows userID as undefined but then an alert in get's return handler shows it to be assigned.
$.get() is asynchronous. You have to use a callback to fill your variable and do the computation after the request is complete. Something like:
$(document).ready(function(){
$.get( "yourUrl", function( data, textStatus, jqXHR ) {
var myData = data; // data contains the response content
// perform your processing here...
registerHandlers( myData ); // you can only pass "data" off course...
});
});
// your function to register the handlers as you said you need to.
function registerHandlers( data ) {
// registering handlers...
}
$.get is an ajax request. A in AJAX stand for asynchronous, so script won't wait for this request to finish, but instead will proceed further with your code.
You can either use complete callback or you can use $.ajax and set async to false to perform synchronous request.
The $.get() function executes an async httprequest, so the callback function will be executed whenever this request returns something. You should handle this callback outside of $.ready()
Maybe if you explain exactly what do you want to do, it would be easier to help!
Are you looking for something like:
$(document).ready(function(){
var variable1, variable 2;
$.get('mydata.url', function(data){
variable1 = data.mydata1;
variable2 = data.mydata2;
});
});
If you declare the variables first, then you can set their values within the get call. You can add a function call at the end of the get handler to call a separate function using these values? Without some kind of example, its hard to go into any more detail.
Without seeing the full code, my guess is that you should declare your variable outside $.ready; initialize it in ready for the initial page load; then update it from the get callback handler.
for example
var x = ""; // declaration
$(document).ready(function() { x = "initial value"; });
$.get(...).success(function() { x = "updated from ajax"; });
I have a function which uses getJSON but its not working like I expected.
function balbla(name, param) {
$.getJSON("/blabla.json?name=" + name + "¶m=" + param, function(data) {
return data.bla;
});
}
When I use alert(data.bla) in the getJSON method it works but when I try return data.bla it doesnt. Also when I create a variable and try to write the value of data.bla to it it simply doesnt work!
// I tried this:
function getRouteData(name, param) {
return $.getJSON('/routes_js.json', {route:name, opt: param});
}
function getRoute(name, param) {
getRouteData(name, param).done(function(data) {
return data.route;
});
}
But when I call getRoute("bla", "blub") it still returns undefined.
AJAX is asynchronous. You cannot easily return a value in such a function that depends on the result of the AJAX call. Change your function to accept a callback:
function balbla(name, param, cb) {
$.getJSON('/blabla.json', {name:name, param: param}, function(data) {
cb(data.bla);
});
}
And use it like this:
balbla('foo', 'bar', function(bla) {
// do stuff
});
An even cleaner way would be returning the jqXHR object:
function balbla(name, param) {
return $.getJSON('/blabla.json', {name:name, param: param});
}
When calling it, use the deferred/promise interface of the jqXHR object to attach a success callback:
balbla('foo', 'bar').done(function(data) {
alert(data.bla);
});
Note that using $.ajax() in synchronous mode is not an option you should consider at all. It may hang the browser's UI (or at least the active tab) until the request finished. Besides that, asynchronous callbacks are the way everyone does it.
If you do not like using callback functions, you could use a preprocessor such as tamejs to generate the asynchronous functions automatically.
The function with your return statement:
function(data) {
return data.bla;
}
… is not being called by your code (it is being called deep inside jQuery), so you have no way to put an assignment of the left hand side of the function call.
It is also being called as part of an asynchronous function, so the balbla function will have finished running and returned before it the anonymous one is ever called.
If you want to do something with the response data, do it inside the anonymous callback function.
getJSON is asynchronous, not synchronous. You need to use a callback so your logic needs to be done in two steps. Calling step and the processing step.
Having some trouble getting this to work, specifically with $.getJSON(). I want to wrap the getJSON function from jQuery in a Javascript function like so:
function reload_data() {
$.getJSON("data/source", function(data) {
$.d = data;
});
}
But when I call reload_data() it doesn't execute the jQuery function inside. Any ideas?
You're not telling us enough. I will just take a guess!
If you are calling this function, and then immediately checking $.d for the results, that is not going to work because you don't allow time for the asynchronous AJAX request to complete...
reload_data();
alert($.d); // What?! It's not displaying the updated results?!
You'll have to utilize a callback structure, like jQuery uses, in order to make it work...
reload_data(function() {
alert($.d);
});
function reload_data(func) {
$.getJSON("data/source", function(data) {
$.d = data;
//Execute the callback, now that this functions job is done
if(func)
func();
});
}
Put an Alert in side the function to know its getting called.
and a try catch around the jQuery call to see if there is an error
function reload_data() {
alert('reload_data start');
try{
$.getJSON("data/source", function(data) {
$.d = data;
});
}
catch (ex){
alert ('error in jQuery call:' + ex)
}
}
Thanks for the help everyone, but the solution was actually really simple. It was just a matter of synchronization. The page was reloading before the JSON data got reloaded, so that's why I wasn't seeing an error.