I have this function in JS:
function redGet(key){
var response;
red.get(key, function (err, reply) {
response = reply;
});
return response;
}
This keeps returning undefined on :
console.log(redGet("hello"));
Assuming that red.get() is an AJAX-like asynchronous function, the problem is that you're expecting it to operate synchronously. You won't be able to get the reply value until the asynchronous operation is complete, which means that anything that relies on this value must be invoked in the callback function.
For example:
function redGet(key){
red.get(key, function (err, reply) {
// do whatever you need to do with the reply value here
console.log(reply);
});
}
redGet("hello");
You don't say what red is, but most likely its .get() method is asynchronous, which means execution of redGet() continues immediately with return response at which point the value is undefined. It is only later after .get() finishes its processing that your callback function is executed to set response - reply.
As with any asynchronous code (also found in Ajax, database access, etc. code) you will likely need to restructure your code such that whatever depends on the return value from .get() is executed in your callback function (or in other functions called from the callback).
I guess that your red.get is an ajax function call (which is asynchronous)
What happen is your console.log(..) get executed before red.get(..) get the result back.
If you still want it to work you have to pass a callback to it e.g.
redGet('hello', function(res) {
alert(res)
})
// then in your code
function redGet(key, cb){
red.get(key, function (err, reply) {
cb(reply)
});
}
You can use jquery $.ajax function with async:false option. May be red variable uses jquery $.ajax function inside and you can do this. But it will affect the performance.
More information on http://api.jquery.com/jQuery.ajax/
Related
I have a piece of code that submits a GET request to another part of my website in a function.
function getStatus(ID) {
$.get('/api/'+ID+'/info', function(statusCallback) {
return statusCallback;
});
}
console.log(getStatus(ID));
What I would expect this code to return and then log would be the information that I need.
What I actually get in console log is
undefined
What can I do to get the actual result?
You're doing async operation. In your case using callback. If you want to print statusCallback, you have to console.log it like Christos mentioned.
Also
console.log(getStatusId())
will return undefined because it's default value returned from the function that has no explicit return. Your function has no return statement, it's only calling some async method.
Btw, try promises instead of callbacks if you can ;)
With ES7 you can use async await
async function getStatus(ID) {
$.get('/api/'+ID+'/info', function(statusCallback) {
// This is executed in the future, but await knows how to deal with it
return statusCallback;
});
}
console.log(await getStatus(ID));
They are a good practice to get started with, because the code gets a lot easier to read.
You need to change your functions as below:
function getStatus(ID) {
$.get('/api/'+ID+'/info', function(statusCallback) {
console.log(statusCallback);
});
}
The function you pass as the second parameter of your get call is called success callback. It will be called, once the get request that is issued on each call of the getStatus function completes successfully. Only then you have access to what the server returned and you can fairly easy access it as above.
Update
If you want to return the data that server sends you have to declare first a variable
function getDataById(ID){
function callback(data){
return data;
}
$.get('/api/'+ID+'/info', function(data) {
return callback(data);
});
}
I've followed this explanation here, but am still unsure how callbacks work.
I do my call here:
scene.foo(scene.myCallBack("mymap"));
And my callback stuff here:
1) scene.foo calls foo and passes in CallBack function with "mymap" JSON data
2) foo's $.ajax defines its success as the passed in CallBack. Once the data is processed, success calls the callback, myCallBack()
3) myCallBack attempts to getJSON from the file name and console.log it as a string with JSON.stringfy
Am I not understanding this correctly?
foo : function (callback) {
$.ajax({
success: callback //once AJAX request is successfull, $.ajax will call callback (myCallBack) and pass response back to callback
});
},
myCallBack : function (name) {
$.getJSON("C:/Users/danniu/Desktop/JavaScript/tilemap/maps/" + name + ".json", function (data) {
var myJSONText = JSON.stringify(data);
console.log("json: " + this.myJSONText);
});
},
You're close to the solution.
scene.foo(scene.myCallBack("mymap")); first exectue scene.myCallBack("mymap") and then the result is passed to scene.foo(...)
It's similar to write:
var result = scene.myCallBack("mymap");
secene.foo(result);
This is pretty weird in this case, because scene.myCallBack("mymap"); doesn't return anything interesting to scene.foo
Note that $.getJSON(...) already does an Ajax request for you.
As soon as you stick parentheses on, it stops being a callback. scene.myCallBack can act as a callback; scene.myCallBack("mymap") is just undefined (the return value of your function, as it does not have an explicit return statement and thus implicitly returns undefined).
If you want to have he $.ajax do myCallBack on success AND have custom arguments with it, you need to wrap it:
scene.foo(function() { scene.myCallBack("mymap"); });
Or equivalently,
fooCallback = function() { scene.myCallBack("mymap"; };
scene.foo(fooCallback);
EDIT to clarify some concepts:
And can you explain why putting parentheses on it makes it not a callback?
Putting parentheses on a function executes a function, giving a value back. A callback must be a function.
For example, let's say your Mum wants you to eat an apple when you get home. She could leave you a note, "Growler, when you get home, eat an apple!":
var eatApple = function() {
growler.eat('apple');
}
growler.on('getHome', eatApple);
is one way to write such a thing. However, if you write
growler.on('getHome', eatApple());
it's like your Mum feeding you an apple, then writing a note "Growler, when you get home, __" and placing the apple core on the blank. I don't know about you, but I'd be rather surprised by such a note; and I daresay your JavaScript interpreter is likewise surprised as well.
A callback is a function to be done at a later time. If you execute it (with parentheses), you are only left with the function's results; and thus the function is not a callback, since your event will try to call back the result (the apple core), and not the function (process of eating an apple).
(An advanced topic is a function that returns a function; in this case, the result can be the callback, such as, growler.on('getHome', whatShouldIDoNow()). whatShouldIDoNow is still not a callback; the function that it would return would be.)
If $.getJSON is already an AJAX request, how can I get the callback from that?
I do not understand the question. You provide $.getJSON with callbacks at the time you invoke it; those functions will be called back at the appropriate time, if such happens.
Hello i have some problem with ajax response handling
i have a global function call() that makes ajax calls and just returns json response:
function call(request_url,params) {
$.post(request_url,params,function(response) {
return response;
},'json');
}
After that i have an object GetServices that uses global function call()
var GetServices = {
service_url:"http://xxx.com/req.php",
getCurrency:function() {
var resp = call(this.service_url,{act:'getCurrency'});
return resp;
}
}
I want GetServices.getCurrency() to return the ajax response but it returns undefined. Javascript assigns value undefined to it and after that finishes ajax call.
Please help me how to fix this.
This pattern will not work because the call is still executing while the resp variable is being set, therefore resp will always be null.
The alternative is to pass a delegate function to the call function to run on $.post success, or change the $.post to be a synchronous $.ajax call.
Its an asynchronous call...
Therefore it will make a call and resume its processing. You will get the value somewhere after making the call. It depends on various factors. For eg, your server's response time.
The easiest way is to call the target function (the function to which you want to pass this ajax value to) from your success handler of $.post()
For eg
function call(request_url,params) {
$.post(request_url,params,function(response) {
yourTargetFunction(response); // instead of returning the value from this
},'json');
}
I'm totally new to javascript and have difficulty in understanding the meaning of the scripts. :( Hope someone can help me or give some advice, thaks! :)
I have a javascript in which it call Ajax function like:
callAjax('../team.cgi', 'POST', data, function(text)
In the ajax2.js it define the function callAjax like:
function callAjax(url, method, data, handler, waittime, timeout_func)
My question is what's the parameter function(text)?
function(text) is the beginning of the definition of an anonymous function. Presumably the call looks something like this:
callAjax('../team.cgi', 'POST', data, function(text)
{
// do something with text
});
The function defined between those brackets takes a variable, text, and does something with it. This is possible in JavaScript because functions are first-class citizens. They can be assigned to variables, defined anonymously, etc.
Typically, you'd say the handler parameter of the callAjax function is a callback. It's a function that will be passed certain arguments when the Ajax call completes. This is typical of asynchronous code.
The snippet above is functionally the same as this:
function doSomethingWhenAjaxCompletes(text) {
// do something
}
callAjax('../team.cgi', 'POST', data, doSomethingWhenAjaxCompletes);
The only difference in the first is that the function isn't defined with the name doSomethingWhenAjaxCompletes; it's defined anonymously instead.
Without seeing the context of the handler function my guess would be that this is the returned value from the ajax call. For example, if team.cgi in your example above returns an xml list of teams then I would expect the text parameter in the handler function to be that list.
When issuing AJAX requests, execution does not halt and wait for the response to come back. Instead, the request is send and execution continues. You simply provide what is called a "callback" function which is called when the AJAX response is returned. Typically, the callback function takes a single argument containing the response object or message that was returned as the answer to your AJAX request.
callAjax('../team.cgi', 'POST', data, function(text) {
console.log('Got a response!');
console.log(text);
}
This simply sends the request. At some time later (after a pause due to network latency) you will see the console log message appear, indicating that a response was received and the callback function meant for "handling" the response has been called.
I've this function
function getTags(level){
$.getJSON("php/get-tags.php", { "parent": level }, function(json) {
return json;
});
}
I'm calling this function as
$(function(){
var tags = getTags('0');
});
The problems is, in the function getTags() the return json is like
{"tags":["Mathematics","Science","Arts","Engineering","Law","Design"]}
but at var tags = getTags('0'), catching the return value, it gets an undefined value.
Is the way I'm returning the value incorrect?
Like many others already correctly described, the ajax request runs asynchronous by default. So you need to deal with it in a proper way. What you can do, is to return the jXHR object which is also composed with jQuery promise maker. That could looke like
function getTags(level){
return $.getJSON("php/get-tags.php", { "parent": level });
}
and then deal with it like
$(function(){
getTags('0').done(function(json) {
// do something with json
});
});
getJSON is asynchronous, the function that called it will have finished by the time the HTTP response gets back and triggers the callback.
You cannot return from it.
Use the callback to do whatever you want to do with the data.
You are trying to call an asynchronous function in a synchronous fashion.
When you call getTags, the it triggers a call to your PHP page, if javascript was blocking, then your page would hang until your server responded with the JSON. You need to re-think your logic and trigger a callback.
function getTags(level){
$.getJSON("php/get-tags.php", { "parent": level }, function(json) {
//do something with the JSON here.
});
}
You cannot return from an AJAX call. It's asynchronous. You need to have all logic dealing with the returned data in the callback.
If you need it to work like that, your getTagsfunction must return a value. It does not at the moment. You could achieve this by using $.ajax and setting async to false.