Consider a Scenario where you have a method called post which is used for making POST Api

The function is defined like this

function post(url, authToken, postBody, callback) {
  // ...
}

Later at some point, you also want to pass the headers to the post function. if you add the extra argument it would look like this

function post(url, authToken, postBody, callback, headers) {
  // ...
}
 
// calling it like this
post('fyndx.io', 'secret-token', {"name": 'Subramanya'}, (err, res) => {
  // some callback implementation
}, {"x-version": "2.0"})

It’s hard to reason about or read this code. A better way would be something like a single argument object

post({
  url: 'fyndx.io',
  authToken: 'secret-token',
  postBody: {"name": "Subramanya"},
  headers: {"x-version": "2.0"},
  callback: (err, res) => {
    // some implementation
  }
})

Now, you can pass only the keys you want to and it also contains the information about each key, like headers is an object and also optional.

Let’s refactor this post so it works with multiple arguments like initial function and also supports single argument object

function post(options) {
  let url,
    authToken,
    postBody,
    callback,
    overrideHeaders = {};
  if (typeof options === 'object') {
    url = options.url;
    authToken = options.authToken;
    postBody = options.postBody;
    callback = options.callback;
    overrideHeaders = options.overrideHeaders;
  } else {
    const args = [...arguments];
    url = args[0];
    authToken = args[1];
    postBody = args[2];
    callback = args[3];
  }
}
  • Let’s check the argument type we received, if it’s object then assign those values to each argument previously we are consuming
  • if it’s the old implemntation of multiple arguments, you can use arguments and destructure it, so you can get list of all the args that are passed to this. Then assign the values in order, to achieve the old functionality