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
Related
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.
Sorry for the ambiguous title, I just didn't know what else to put. Im learning JS and in the video the person does this.
When he calls the addListAfterKeyPress method at the bottom, why does the function call work? I thought he would have to put in a argument for the addListAfterKeyPress to take in since it has an event parameter. But in the end the code works perfectly. And also, when can i call a function that takes a parameter without explicitly passing one like how he did it in the picture?
This is a so called callback.
addListAfterKeypress at line 30 is not a call to this function, it is just saying, whenever the event keypress is raised on this input element, call this function.
Who is calling the function is the DOM library, indeed. You just have to pass a pointer to the function to be called.
Even more, the addListAfterKeypress function expects an event parameter, which will be provided to the function by the DOM library.
I think it is a bit more understanding by looking at an annonymous function there.
input.addEventListener('keypress', event => {
// This will be run whenever the input raises an event of type 'keypress'
// Here, the DOM library provides me an event parameter
});
Edit on demand:
Be aware, I am using ES6 just for comfort.
Suppose having this function
const callback = () => {
console.log(`My callback function is being executed`);
};
I will be using setTimeout to mock the HTML events. setTimeout is a function that expects a callback to execute after n milliseconds.The first parameter is the callback itself, the second is the amount of milliseconds, n.
See https://www.w3schools.com/jsref/met_win_settimeout.asp
setTimeout(callback, 500); // After 500ms, function callback will be fired
Here, I am just passing a pointer to the setTimeout function. This pointer must point to a function that will be called by setTimeout.
Let's write our own function that takes a callback as a parameter.
const callback2 = (number) => {
console.log('I received this parameter', number);
};
const callbackWrap = (callback, n) => {
// Here, callback parameter is a function that I can invoke, actually
console.log('The wrapper will execute the function passed as parameter');
callback(n);
};
Now, we can call the wrapper pointing to the new callback (callback2).
callbackWrap(callback2, 3);
callbackWrap(callback2, 4);
Or, we can define our function directly on the parameter list.
That is, we are passing an annonymous function
// p is the parameter of the callback function
callbackWrap(p => {
// Since callbackWrap will call the function parameter
// by passing a single parameter,
// the function I am declaring, expects that parameter
console.log(`Received ${p} inside the annonymous function`);
}, 'Parameter');
So, to summerize a bit, just the same way you can declare a variable (let's say, of type number) and then pass it to a function as a parameter, you can declare a function to pass it the same way.
const normalParameter = 30;
const functionParameter = p => console.log('Another callback', p);
callbackWrap(functionParameter, normalParameter);
// Or maybe passing more complex parameters
const anotherParameter = [1, '2', {3: 4}];
callbackWrap(functionParameter, anotherParameter );
Hope it clarifies a bit.
My questions here is about the way the call back function works.
const fs = require('fs');
let fileContents = 'initial value';
fs.readFile('file.txt', 'utf-8',function(error,res){
fileContents = res;
console.log(fileContents);
})
So, when the fs.readFile runs, the function(error,res) is called. But why does the fileContents receives the text inside the txt file if my parameter is empty?
I'm assuming that the readFile adds the value read to the res parameter.
Is it always like this?
Another questions is why do I get null when I erase error?
Readfile looks like something like this:
function readFile(path, cb) {
try {
// Some very complicated stuff
// All fine, call callback:
path(/*error:*/ null, /*res: */ "somedata");
} catch(error) {
path(error, /*res: */ undefined);
}
}
So what you get inside the callbacks parameter does not depend on its name, but on its position, so when you do:
readFile("/..", function(res) { /*...*/ });
res will be the error readFile passes back, and if thats null its a good thing.
Maybe take a little time to experiment with callback functions.
A callback function is just a function that you pass as a parameter to another function. In the code below I declared my function. myFunc uses another function as parameter to the function called callback. Inside my function I invoke the function and pass myName as parameter to the callback. This allows me to declare other anonymous functions as parameters which I included as examples. When myFunc is invoked it invokes the callback inside its local environment.
I can then manipulate the data that is passed to the callback and write my own code inside the anonymous function using the variable that is passed to myFuncs callback.
In your example you are using readFile which retrieves the data from the file and passes it to a callback function and/or passes an error assuming something went wrong.
function myFunc( callback){
let myName = "Joe Smo";
callback(myName);
}
/*
Now I can use my function and add another anonymous function to do whatever I want
provided I use the same parameters that are inside my function.
*/
myFunc(function(name){
console.log("What's up!"+name);
});
myFunc(function(strangeName){
console.log(strangeName+" is a strange name.");
});
I have this piece of code below:
It makes a GET call to an URL, gets some object, and appends an image to an HTML tag.
function getDataFromApi(searchTerm, callback) {
const URL1 = `some url`;
const design = {
url: URL1,
data: {
"dog breed name": searchTerm
},
type: 'GET',
success: callback
};
$.ajax(design);
}
function displaySearchData(data) {
const allResultsLength = data.message.length;
const ranNum = Math.floor(Math.random() * allResultsLength);
const dogResults = data.message[ranNum];
$(`.js-search-results`).html(`<img src = ${dogResults}>`);
}
function watchSubmit() {
$('.js-search-form').submit(event => {
event.preventDefault();
let queryTarget = $(event.currentTarget).find('.js-query');
let query = queryTarget.val();
queryTarget.val("");
getDataFromApi(query, displaySearchData);
});
}
$(watchSubmit);
I get the getDataFromApi and watchSubmit but getDataFromApi(query, displaySearchData); isn't intuitive to me at all.
I've been writing Java, and it doesn't make sense to me how displaySearchData is getting called without the parameter - it seems that line should be getDataFromApi(query, displaySearchData(data));.
Can someone please explain how this is getting compiled & executed (basically how this is a legitimate syntax) in javascript?
Somewhere in the good'ol jquery, there lies this piece of code:
$.ajax = function(config){
...
// get the response from XHR request,
// and save it in, say, 'response'
...
// now check, if the response is OK 200
// and if so, execute next line
// which is basically - calling your displaySearchData method
config.success(response);
...
}
now, config is your design object, which has a property success which carries the reference to your displaySearchData method.
The data argument of method displaySearchData will now carry the reference to variable response passed in the method invocation config.success(response).
EDIT: the argument callback also carries forward the reference of the method displaySearchData to getDataFromApi
Concept to be noted:
functions can be passed in Javascript as arguments to another function, in which case we only need the referring variable to be passed as argument. Invocation parentheses () are not required.
function A(data){...};
function b(referenceToFunctionA){
...
referenceToFunctionA(someData);
...
};
// correct
b(A);
// wrong, because adding () after any function reference variable
// invokes the method immediately.
// in this particular case the returned value of the method A
// is passed as argument instead of the reference to method A itself.
b(A());
Welcome to JavaScript My Friend. Get ready to experience more magical weirdness as you continue to work on JS. Good luck.
What you need to look at is in the function getDataFromApi().
In that function, you have a "callback" parameter. This parameter is later added into $.ajax. This is a jQuery function that will provide some callback when a certain condition is matched (like before sending a request, when the response has been received,...). This $.ajax callback provide you with 3 parameters, one of them is data (which are being used, textStatus, and jqXHR. Usually, you only need to pay attention to the data since it contains the response from where you are requesting data.
So when the $.ajax success, the "callback" function will be called, which is the displaySearchData. And since $.ajax callback provides you with the data parameter, you can add them to the parameters of displaySearchData. Do note that you can add the extra 2 provided parameters if needed.
You can have a look at that function here: jQuery Ajax
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.