Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJS default parameter when last parameter is the callback

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 ?

like image 498
IggY Avatar asked Nov 19 '15 13:11

IggY


People also ask

Can a callback function have parameters?

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.

Which is the first argument usually passed to a node js callback handler?

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).

What is default parameter can we use default parameter for first parameter in function?

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.

How do you pass a parameter in callback function in node js?

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() .


3 Answers

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.

like image 156
Victor Avatar answered Nov 17 '22 19:11

Victor


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!

like image 41
Tamas Hegedus Avatar answered Nov 17 '22 19:11

Tamas Hegedus


Code

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}

Explanation

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.

like image 3
Juan Cortés Avatar answered Nov 17 '22 19:11

Juan Cortés