Callback function syntax - why is this not allowed? - javascript

function callbackFn(res){console.log(res)}
I can write
$.get("./a", function(response) {callbackFn(response)});
Why can't I write
$.get("./a", callbackFn(response));

Just pass the function reference to $.get()
$.get("./a", callbackFn)
Demo
function handleResponse(data) {
console.log('response data:\n', data);
}
$.getJSON('https://jsonplaceholder.typicode.com/todos/1', handleResponse)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Functions are values in javascript, special objects is you will.
When you define a function like
function callbackFn(res) {
console.log(res)
}
callbackFn references the function itself and callbackFn() executes or call the function and you get the value that this function returns.
The method you are showing is expecting an string as the first parameter and a function as the second.
So if you do:
$.get("./a", callbackFn(response));
You are passing to $.get the return value of calling the function with the argument response (ie. callbackFn(response)).
To make it clearer, this is how a method like this is defined (this is an example, not the actual implementation)
function get(path, callback) {
fetch(path).then(function (response) {
callback(response)
})
}
As you can see, inside get, it's calling the function that is expected as a second parameter with the argument response (your callbackFn).

The second version calls callbackFn() immediately, and uses its return value as the second argument to $.get(). It's equivalent to
var temp = callbackFn(response):
$.get("./a", temp);
You need to wrap it in an anonymous function so that it won't be called immediately, but instead when $.get completes the AJAX request.

Related

Passing callback functions as arguments in vanilla JS ajax

I am working on an ajax function to retrieve info from the database. I set up the API and the ajax function does retrieve proper values, but the callback function I passed as an argument won't work on onreadystatechange.
Simplified Code below
function serializeArgs(args) {
//Serialize Arguments
}
function callback(a) { //The function to be called as callback
//Process the response and add contents to the page
}
function getListData(callback) {
var ajaxOptions = {
action: "get_data",
}
var request = new XMLHttpRequest();
request.open("POST", apiurl, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
request.setRequestHeader("Accept-language", "en-US");
request.onreadystatechange = function(event) {
if (this.readyState == 4 && this.status == 200) {
callback(this.response);
}
};
request.send(serializeArgs(ajaxOptions));
}
When I run the function, I get the error "TypeError: callback is not a function"
I have been struggling with this all day, but since I am not that experienced with ajax, I could not figure out why this is happening, and how to solve it. I have a hunch that it has something to do with the asynchronous nature of the ajax, but I'm not sure how I can work around this.
Short reference for this error:
You usually get this error when the following happens:
When a function call is made on a property of that simply isn’t a function.
When a function call is made on an object type that doesn’t contain that function or method.
When a function call is made on a built-in method that expects a callback function argument to be provided, but no such function exists.
I noticed the following in your ajax function:
Your parameter is named callback, just like your function callback. What your ajax function is trying to do is use the parameter callback as a function (not sure if you pass the function callback in as a parameter, if you do, then it's alright, but since I cannot see where you are calling getListData function, I can only guess you are calling it without passing the function callback as an argument).
//Your function callback is trying to access this parameter.
//So unless your actual function callback is being passed in as an argument,
//it's most likely trying to access your parameter even though it is NOT a function or it isn't even receiving a function as parameter
function getListData(callback)
function callback(a)
However if you are trying to simply access it as a function (and not as a callback) i'd recommend changing the parameter name or function name callback.
So to show an example:
First way of doing what you are trying to achieve (callback way).
Call your function this way:
getListData(callback)
Or do the following:
function getListData(changedParamName) {
//this way you can now call your callback function and pass this.response to it
}
That should do the trick.
Where do you call the function getListData?
My guess is, that you call it like getListData() without passing the callback function.
if you call it like getListData(callback) it should work. Hard to say what happens without the full code example.
just for testing you also can change the line
function getListData(callback) {
to
function getListData() {
just to see if it works.
In the second szenario, you don't pass the callback, so when you call the callback function, Javascript will look for it in the parent scope.

Passing variables from the external function to the callback function in JavaScript

I'm a bit confused about using callback functions in JavaScript, when doing the following call for example:
func(obj , callback);
and let's assume that func sends some AJAX request , and gets an object as a response,let's call it resObj, do I need to pass it to the callback if I want to use it there? Thank You
when doing a func(obj, callback); call for example, do I need to pass the result to the callback if I want to use it there?
No, you don't. func will pass the result into callback when calling it back, that's the whole point. You only need to accept it as a parameter when writing the callback function.
function func(o, cb) {
setTimeout(function() { // or ajax request or whatever
const resObj = o.example + 3;
cb(resObj); // here the result is passed to the callback
}, 50);
}
function callback(resObj) {
console.log(resObj);
}
const obj = {example: 38};
func(obj, callback); // You're not *calling* the callback here

Understanding callback function parameters

I've been trying to understand callback functions and I'm unsure where the data variable/object is actually coming from in this example:
$.get( "ajax/test.html", function( data ) {
console.log(data);
});
I think of this function being defined as something like this:
$.get = function(url, callback) {
// send request to url
callback(data); // execute callback function... but where is data coming from/being defined?
};
I've been trying to understand callback functions and I'm unsure where
the data variable/object is actually coming from in this example:
you invoked jquery function $.get() and gave a handle to your anonymous function as a parameter. jquery did all the work on invoking ajax methods, getting the response (data) and finally invoke your anonymous function (which you passed on to it as parameter). data variable is then passed on to this anonymous function by the same jquery function.

Why is return not working in getJSON and why cant I write into variable from getJSON?

I have a function which uses getJSON but its not working like I expected.
function balbla(name, param) {
$.getJSON("/blabla.json?name=" + name + "&param=" + 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.

javascript callback question

I have a javascript which I didn't write but I need to use it ..
function function1()
... body..
and at the end
I have this
'callback': 'getListCallback'
}
What does this callback mean and getListCallback = function(obj) is another function, does this mean that results from function1 are returned to function getListCallback?
Tnx
A callback function is a function that is going to be called later, usually when some event occurs. For example, when adding an event listener:
function callback(){
alert("click");
}
document.body.addEventListener("click", callback, true);
In many cases you pass the callback function as an anonymous function:
setTimeout(function(){alert("It's been 1 second");}, 1000);
The code getListCallback = function1(obj); will not call getListCallback with the results of function1(obj). It will store whatever function1(obj) returns into getListCallback. If function1 returns a function, then you can call that function later, like so:
function function1(obj){
return function(){
alert("getListCallback was called. obj = "+obj);
}
}
getListCallback = function1(1);
getListCallback();
Yes, it should mean that
normally a callback function means a function which will call after current function execution finished.
This
getListCallback = function(obj){// do something} is like assigning this "function(obj){//....}" to a variable which can use in any place where you need to use that function.

Categories