DEV Community

loading...
Cover image for A creative way to have required arguments in JavaScript

A creative way to have required arguments in JavaScript

gabrielrufino profile image Gabriel Rufino ・3 min read

Have you ever received an error because you forgot to pass an argument to the function? This is a common situation.

Unfortunately, JavaScript does not require passing parameters that have been declared in the function, and this results in a possible later error.

Let's see an example. Consider we've got a function that must receive a string and return if that string contains de letter "G".

file.js

function includesG(string) {
  return string.includes('G')
}

console.log(includesG('Gabriel Rufino')) // true
Enter fullscreen mode Exit fullscreen mode

This works fine! But there's a problem: what happens if I call the function includesG without an argument?

file.js

function includesG(string) {
  return string.includes('G')
}

console.log(includesG())
Enter fullscreen mode Exit fullscreen mode

Let's execute using Node:

$ node file.js
/home/gabrielrufino/Desktop/file.js:2
  return string.includes('G')
                ^

TypeError: Cannot read property 'includes' of undefined
    at includesG (/home/gabrielrufino/Desktop/lab/lab.js:2:17)
    at Object.<anonymous> (/home/gabrielrufino/Desktop/lab/lab.js:5:13)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47
Enter fullscreen mode Exit fullscreen mode

It seems to be a pretty violent error 😅

There's a much better way to report the absence of an argument to the developer: we can combine the power of the default params with the throw of a more descriptive error.

Let's do it step by step. First, we define the function responsible for throw the error. I'm gonna call it isRequired.

file.js

function isRequired(argument) {
  throw new Error(`The argument ${argument} is required`)
}

function includesG(string) {
  return string.includes('G')
}

console.log(includesG())
Enter fullscreen mode Exit fullscreen mode

The function isRequired is nothing more than a function that throws a custom error based on the name of the argument.

Now that we have this function, we can use it as the default param of the required argument or arguments.

Wait for it...

file.js

function isRequired(argument) {
  throw new Error(`The argument ${argument} is required`)
}

function includesG(string = isRequired('string')) {
  return string.includes('G')
}

console.log(includesG())
Enter fullscreen mode Exit fullscreen mode

Now, always we forget to pass the argument string, the default value will be assumed and the default value is the throw of an error.

Let's run the code:

$ node file.js
/home/gabrielrufino/Desktop/file.js:2
  throw new Error(`The argument ${argument} is required`)
  ^

Error: The argument string is required
    at isRequired (/home/gabrielrufino/Desktop/lab/lab.js:2:9)
    at includesG (/home/gabrielrufino/Desktop/lab/lab.js:5:29)
    at Object.<anonymous> (/home/gabrielrufino/Desktop/lab/lab.js:9:13)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47
Enter fullscreen mode Exit fullscreen mode

And now, we've got a more descriptive error saying that we forgot the parameter string.

"Ok, Gabriel! But don't we replace one error with another? How does it help me?"

Errors were created to help us! They must tell us what specifically is wrong. The first error doesn't help us to find out what is the problem, it only says that the value undefined doesn't have the method includes. It's so much generic to find the problem. The error we've created says explicitly that we forgot the argument 😄

Thank you!

Discussion (8)

pic
Editor guide
Collapse
seanmclem profile image
Seanmclem

Or, typescript

Collapse
gabrielrufino profile image
Collapse
bytebodger profile image
Adam Nathaniel Davis

Yep. This is the same thing that I did in this article (which is now encapsulated in its own NPM package): dev.to/bytebodger/better-typescrip...

Collapse
gabrielrufino profile image
Collapse
mattdevio profile image
Matt G

Interesting convention, What happens if you need a default variable though?

Collapse
gabrielrufino profile image
Gabriel Rufino Author

Hey man :D

If you can have default parameters, you don't need to require the variable. If you need to require the parameter, it doesn't make sense to have default parameters.

Collapse
kwadoskii profile image
Austin Ofor

Then the required method is not needed, since the original function always gets an argument parsed to it.

Collapse
said321 profile image
Said Choukrane

Usefull trick, thanks