I have a function like this one (simplified) :
doSmthg (name, age, callback) {
callback(name, age);
}
I'd like to have a default value for age if it's not provided.
I know I could do doSmthg(name, callback, age=42) {...}
in ES6 but I've been told callback should always be the last parameter as it make the call to the function more readable.
For now the solution I found is to do the following :
doSmthg (name, age, callback) {
if (arguments.length === 2) {
age = 42;
callback = age;
}
}
But I find this solution hard to read.
Is this the good solution ? Is there a better one ?
Using the Array. forEach() method as an example, the callback function will always receive the current item, its index, and the array itself as arguments, in that order. You can name the parameters for them anything you want, or even omit them entirely, but the method will always pass them in as arguments.
Traditionally, the first parameter of the callback is the error value. If the function hits an error, then they typically call the callback with the first parameter being an Error object. If it cleanly exits, then they will call the callback with the first parameter being null and the rest being the return value(s).
The default parameter is a way to set default values for function parameters a value is no passed in (ie. it is undefined ). In a function, Ii a parameter is not provided, then its value becomes undefined . In this case, the default value that we specify is applied by the compiler.
Because Node. js works asynchronously, things might not work as you think, if you are still stuck in the synchronous world.. To pass variables into callback function, you can use bind() .
For this kind of situation you can use something like this:
function doSmthg(name, age, callback) {
if (typeof age === 'function') {
callback = age;
age = DEFAULT_VALUE;
}
//continue
}
Or you can use a Hash of options, that i think it's better because makes the code more readable, depending of the number of parameters:
function doSmthg(options, callback) {
var name = options.name;
var age = options.age || DEFAULT_VALUE;
//continue
}
doSmthg({ name: 'batman' }, function() {});
Also you can use the underscore #extend
function to merge the options with the default values.
If you have access to spread operator:
function foo(...args) {
const callback = args.pop();
const [name, age = 42] = args;
// ...
}
But I think it's time to use promises in NodeJS as well.
function foo(name, age = 42) {
return new Promise(resolve => {
setTimeout(() => resolve({name, age}), 1000);
});
}
//...
foo('Sándor').then(x => console.log(x)); // { name:"Sándor", age:42 }
Using ES6 promises you can get rid of the so called "callback pyramid", and makes it possible to use your function with ES7 async-await
keywords. The future is here!
function foo(args, callback){
parsed = {name:"John Doe",age:12}; //default values
for(a in args) parsed[a] = args[a];
//Arguments are accessible like parsed.name
callback(parsed);
}
function callback(args){
alert(JSON.stringify(args));
}
foo({name:"Peter",extra:2},callback);//yields {"name":"Peter","age":12,"extra":2}
foo({name:"Mark",age:92},callback); //yields {"name":"Mark","age":92}
foo({},callback); //yields {"name":"John Doe","age":12}
Depending on the number of arguments to pass it might look too verbose to your liking. The concept should be self explanatory but to put it in words, we group the arguments in an object and inside the function have an object with the default values (if needed). Then we override the defaults with those passed leaving us a very clear and clean callback
and verbose args.
Note that if extra parameters are passed, those are not lost in the process of setting the defaults.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With