Categories
Express JavaScript Answers

How to Add a Single Routing Handler for Multiple Routes in a Single Line with Express?

To add a single routing handler for multiple routes in a single line with Express, we can pass in an array of route path patterns that will be handled by one route handler.

For instance, we can write:

const express = require('express')
const app = express()
const port = 3000

const routes = ['/', '/foo', '/bar', '/baz/:id']
app.get(routes, (req, res) => {
  res.send('hello world')
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

We have the routes array that has strings with different route path patterns.

And we use it as the first argument of the app.get method.

Therefore, when we go to / , /foo , /bar or /baz with anything after it, we’ll see hello world displayed.

This also works with app.post , app.delete , app.put , and other route defining methods.

Categories
JavaScript

Using Default Parameters and the Rest Operator in JavaScript

With the 2015 version of JavaScript, JavaScript functions can now accept default parameters in functions and there’s the rest operator to capture optional arguments in an array.

This is handy for handling optional parameters and there are many use cases for these features. Before we had these two features, all we had was the arguments object with the list of arguments of the function that was called.

All we could do to prevent undefined errors for optional parameters was to check each argument directly to see if they were defined and then set the value directly.

This is painful for developers as it’s possible to have a long list of optional arguments that we want the function to get. With default parameters, the default value for parameters is set directly in the signature of the function. This eliminates many lines of code that check the code.

Default Parameters

Default parameters are easy with JavaScript. To set them in our code, we write the following:

const sum = (a,b=1) => a+b

In the code above, we set the default parameter value of b to 1, so if the second argument isn’t passed in when we call the sum function, then b is automatically set to 1.

So, if we call sum as follows, we get 2 returned:

sum(1)

As we can see, now we don’t have to worry about having optional arguments being undefined, which would be the alternative result if no default value is set for parameters. This eliminates many sources of errors that occur when making parameters optional with JavaScript.

The alternative way, without using default parameters, would be to check if each parameter is undefined. We write the following to do this:

const sum = (a,b,c)=>{
  if (typeof b === 'undefined'){
    b = 1;
  }

  if (typeof c === 'undefined'){
    c = 1;
  }
  return a+b+c;
}

If we call the following sum function without parameters, we get:

const sum = (a,b = 1,c = 1)=> a+b+c;
sum(1) // returns 3
sum(1, 2) // returns 4

As we can see, we handled missing parameters gracefully with default parameters.

For default parameters, passing in undefined is the same as skipping the parameters. For example, if we call the following function and pass in undefined, we get:

const sum = (a,b = 1,c = 1)=> a+b+c;
sum(1,undefined) // returns 3
sum(1,undefined,undefined) // returns 3
sum(1, 2,undefined) // returns 4

Note that undefined is the same as skipping parameters.

This isn’t true for other falsy values that are passed into a function. So, if we pass in 0, null, false, or empty string, they get passed in and the default parameter values will be overwritten.

For example, if we have the code below:

const test = (num=1) => typeof num;
test(undefined);
test(null);
test('');
test(0);
test(false);

We get number for test(undefined), object for test(null), string for test(string), number for test(0), and boolean for test(false).

This means that anything other than undefined is passed in, but note that if we pass in falsy values and then run arithmetic operations on them, falsy values get converted to 0.

const sum = (a,b = 1,c = 1)=> a+b+c;
sum(1,null)
sum(1,null,false)
sum(1, 2,'')

So, sum(1, null) returns 2 as b is converted to 0 and c has the default value of 1.

sum(1) returns 1 as b and c are converted to 0. sum(1, 2,’’) is 3 as a is 1, b is passed in so that it becomes 2 instead of getting the default value of 1, and c is an empty string which is converted to 0.

Default arguments are evaluated at call time, so that they’re set each time they’re called if no argument is passed into the function parameter with default values.

For example, if we have:

const append = (val, arr = [])=>{
  arr.push(val);
  return arr;
}

append(1);
append(2);

append(1) returns [1] and append(2) returns [2] as we didn’t pass in an array to each function call, so arr is set to an empty array each time it’s run.

It’s also important to know that we can pass in values returned by functions in the default parameter, so if we have a function that returns something, we can call it in the default parameter and assign the returned value to the parameter.

For example, we can write:

const fn = () => 2
const sum(a, b = fn()) => a+b;

Then, if we call sum(1), we get 3 as the fn function returns 2. This is very handy if we want to manipulate and combine values beforehand, before assigning it as a parameter.

Another great feature of the default parameters is that the parameters left of the given parameter are available for the parameter for assignment as default values, so we can have a function like the function below:

const saySomething = (name, somethingToSay, message = `Hi ${name}. ${somethingToSay}`) => ({
  name,
  somethingToSay,
  message
});

Notice that we assigned an expression to the message parameter in the saySomething function. This is great for manipulating data and then assigning as we did before by assigning the function.

We can also see that we can have default parameters that depend on parameters that are to the left of it. This means that default parameters do not have to be static.

So, we call it with the first two parameters filled in, like saySomething(‘Jane’, ‘How are you doing?’). We get:

{name: "Jane", somethingToSay: "How are you doing?", message: "Hi Jane. How are you doing?"}

The message is returned with the template string that we defined evaluated.

We cannot call functions nested inside a function to get the returned value as the default parameter value. For example, if we write:

const fn = (a = innerFn())=>{
  const innerFn = () => { return 'abc'; }
}

This will result in a ReferenceError being thrown, because the inner function isn’t defined yet when the default parameter is defined.

We can also have default parameter values that are set to the left of required parameters. Arguments are still passed into parameters from the left to the right, so if we have:

const sum = (a=1,b) => a+b

If we have sum(1), we have NaN return 1. It is added to undefined as we didn’t pas in anything for the second argument, so b is undefined.

However, if we write sum(1,2) then 3 is returned as we have a set to 1 and b set to 2.

Finally, we can use a destructuring assignment to set default parameter values. For example, we can write:

const sum = ([a,b] = [1,2], {c:c} = {c:3}) => a+b+c;

Then, we call sum without arguments. We get 6 because a is set to 1, b is set to 2, and c is set to 3 by the destructuring assignment feature that JavaScript provides.

Rest Operator

The rest operator is a JavaScript operator where we can store an indefinite number of arguments in a function as an array.

It looks exactly like the spread operator, which lets us spread entries of an array or a list of key-value pairs of an object into another object.

For example, if we have a function that has a long list of arguments, we can use the rest operator to shorten the list of parameters in a function.

The rest operator is used with the following syntax:

const fn = (a,b,..restOfTheArgs) => {...}

Where restOfTheArgs is an array with the list of arguments other than the first two. For example, if we want to write a sum function that takes an indefinite list of numbers as arguments and sum up the numbers, we can write:

const sum = (a,b,...otherNums) => {
  return a + b + otherNums.reduce((x,y)=>x+y, 0);
}

As we can see, this is very handy for functions that have a list of arguments. Before we had this, we had to use the arguments object available in functions to get a list of arguments.

This is not ideal, as we allow them to pass in anything into the arguments. With the rest operator, we have the best of both worlds. We can have some fixed parameters, while the rest stays flexible.

This makes functions more flexible than functions with a fixed number of parameters, while having some flexibility with functions that take an indefinite number of arguments.

The arguments object has all the arguments of the function. Also, it’s not a real array, so array functions aren’t available to them. It’s just an object with indexes and keys to denote the argument’s positions.

Methods like sort, map, forEach, or pop cannot be run on the arguments object. It also has other properties. This creates confusion for programmers.

The arguments that are converted to an array with the rest operator do not have these issues, as it is a real array.

To call the sum function we wrote, we can write:

const result = sum(1,2,3,4,5,6,7,8,9,10);

result will be 55, as we summed up all the arguments together. otherNums is an array with all the numbers other than 1 and 2.

We can also use the rest operator to destructure a list of arguments into a list of variables. This means that we can convert a list of parameters into an array with the spread operator, and then decompose the array of arguments into a list of variables.

This is very useful because we can get the entries of the array that’s operated on by the rest operator and convert them to named variables.

For example, we can write:

const sum = (a,b,...[c,d,e])=> a+b+c+d+e;

This way, we can use the rest operator but limit the number of arguments that your function accepts.

We take the function parameters a and b, and we also take c, d, and e as parameters. However, it’s probably clearer without using the rest operator as all the parameters are fixed, we can just list the parameters directly.

Conclusion

Now that we have the 2015 version of JavaScript, we can do many handy things with parameters.

Default values and the rest operator are handy for handling missing or operation parameters. Default parameters let us set default values for parameters that might not have anything passed in in function call arguments.

The rest operator lets us retrieve some or all items listed in the argument as an array. Letting us manipulate them with array operations or using the destructuring assignment to decompose them into individual variables.

Categories
JavaScript

Using Callbacks and Closures in JavaScript

Callbacks and closures are used frequently in JavaScript. Callbacks are functions that are passed into another function as an argument. Closures are functions that are nested in other functions, and it’s often used to avoid scope clash with other parts of a JavaScript program.

Callbacks

Functions in JavaScript are objects. Like any other object, you can pass them in as a parameter. Therefore, in JavaScript we can pass in a function as an argument of another function. This is called a callback function. Functions can also be returned as the result of another function. Callback functions can be used for synchronous code and asynchronous code.

Passing in a function as a parameter of another function is different from calling a function. When we call a function, we add parentheses to the end of the function possibly with arguments inside. Functions that are called run immediately. When functions are passed in as an argument, they aren’t called immediately. They’re called when the function that you passed the callback function into calls it. For example, if we have:

element.addEventListener('click', handleClick);

handleClick isn’t called immediately. It’s called when a click event is triggered by the user.

We can write our own function that takes a callback function as an argument by adding a parameter that takes a function. For example, we can write:

const calculate = (x, y, callbackFn)=>{  
  return callbackFn(x, y);  
})

where callbackFn is a function parameter that runs inside the calculate function. If we want to use the calculate function to calculate something, then we write:

const result = calculate(1, 2, (x, y)=>{  
  return x + y;  
});

result would is 3 above since we added the 2 numbers x and y in the callback function that we passed in. We can also pass in a named function as a callback function:

const add = (x, y) => x + y;  
const result = calculate(1, 2, add);

We would get the same result. Also, if our function takes callback function, we can take in any other function as an argument:

const add = (x, y) => x + y;  
const subtract = (x, y) => x - y;  
const multiply = (x, y) => x * y;  
const divide = (x, y) => x / y;  
const sum = calculate(1, 2, add); // 3  
const difference = calculate(1, 2, subtract); // -1  
const product = calculate(1, 2, multiply); // 2  
const quotient = calculate(1, 2, divide); // 0.5

As we can see, callback functions make our code more flexible as we can pass in whatever function we want as a callback function. Also, named functions are easier to read since we separated the callback function from the arguments. They can also be reused in other places easily.

However, we didn’t check that the callbackFn parameter is actually a function. This is going to be an issue if someone passes in something that isn’t a function. To check that it’s actually a function, we use the typeof operator, as follows:

const calculate = (x, y, callbackFn)=>{  
  if (typeof callbackFn === 'function'){  
    return callbackFn(x, y);  
  }  
  return 0;  
})

To use callback functions in our web page, we put the following in index.html :

<html>  
  <head>  
    <title>Calcuate</title>  
    <link href="styles.css" rel="stylesheet" type="text/css" />  
  </head>  
  <body>  
    <p>  
      The sum of 1 and 2 is <span id='sum'></span>  
    </p> <p>  
      The difference of 1 and 2 is <span id='difference'></span>  
    </p> <p>  
      The product of 1 and 2 is <span id='product'></span>  
    </p> <p>  
     The quotient of 1 and 2 is <span id='quotient'></span>  
    </p> <p>  
      The modulus of 1 and 2 is <span id='modulus'></span>  
    </p>  
    <script src="script.js"></script>  
  </body>  
</html>

Then in script.js we put:

const calculate = (x, y, callbackFn) => {  
  return callbackFn(x, y);  
};

const add = (x, y) => {  
  return x + y;  
}

const subtract = (x, y) => {  
  return x - y;  
}

const multiply = (x, y) => {  
  return x * y;  
}

const divide = (x, y) => {  
  return x / y;  
}

const mod = (x, y) => {  
  return x % y;  
}

window.onload = ()=>{  
  const sum = calculate(1, 2, add);  
  const difference = calculate(1, 2, subtract);  
  const product = calculate(1, 2, multiply);  
  const quotient = calculate(1, 2, divide);  
  const modulus = calculate(1, 2, mod);  
  document.getElementById('sum').innerHTML = sum;  
  document.getElementById('difference').innerHTML = difference;  
  document.getElementById('product').innerHTML = product;  
  document.getElementById('quotient').innerHTML = quotient;  
  document.getElementById('modulus').innerHTML = modulus;  
}

Closures

A closure is a local variable or function that’s used by another function and the references to the function returned to the function. That is, we return a function in an outer function that references to the local variables of the outer function. This is possible if we have functions nested in another function and returned as a reference. In the inner function, we can use the variables of the outer function. Because of the scoping of local variables, inner functions can access the variables of the outer function. When we return the inner function in the outer function, the references to the local variables of the outer function are still referenced in the inner function.

For example, we can write the following code to return a function from an outer function:

const hello = (name)=>{  
  const greeting = `Hello ${name}`;  
  const greet = () => alert(greeting);  
  return greet;  
}  
const helloJane = hello('Jane');  
helloJane();

helloJane is a function that’s returned by hello. Note that we still reference the greeting variable in the helloJane function. We get an alert box that says ‘Hello Jane’ in it. The local variable greeting is still accessible because we passed it into the greet function. Because the greet function has the greeting function passed in. However, the name parameter isn’t accessible to the outside anymore because we didn’t pass it to the greet function when we return it. As we can see closures allow us to have private data in our code while keeping access to some public data from the outside.

We can expand the example above to make functions to show any greeting. In index.html :

<html>  
  <head>  
    <title>Calcuate</title>  
    <link href="styles.css" rel="stylesheet" type="text/css" />  
  </head>  
  <body>  
    <p id='hello'></p>  
    <p id='welcome'></p>  
    <p id='how-are-you'></p>  
    <p id='goodbye'></p>  
    <script src="script.js"></script>  
  </body>  
</html>

In script.js , we write:

const createGreetingFn = (message)=>{  
  const greeting = message;  
  const greet = () => greeting;  
  return greet;  
}

window.onload = ()=>{  
  const hello = createGreetingFn('Hello');  
  const welcome = createGreetingFn('Welcome');  
  const howAreYou = createGreetingFn('How are you?');    
  const goodBye = createGreetingFn('Goodbye');  
  document.getElementById('hello').innerHTML = hello();  
  document.getElementById('welcome').innerHTML = welcome();  
  document.getElementById('how-are-you').innerHTML = howAreYou();  
  document.getElementById('goodbye').innerHTML = goodBye();  
}

As we can see, we can create multiple functions from the same function that does different things. A function that creates new functions is called a function factory. We created functions that different things from one function. This is another way to make our JavaScript more flexible and let us reuse our code. In the window.onload function, we called the functions that we created by the createGreetingFn that we called, which returns the results and then assigned the results to the innerHTML property of our elements.

Categories
Express JavaScript Answers

How to Accept Multiple URL Parameters in Express Routes?

To accept multiple URL parameters in Express routes, we can put them as the placeholders for each URL parameter in the route path string.

For instance, we can write:

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('hello world')
});

app.get('/fruit/:fruitName/:fruitColor', (req, res) => {
  const {
    fruitName,
    fruitColor
  } = req.params
  res.json({
    fruitName,
    fruitColor
  });
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

We add the ‘/fruit/:fruitName/:fruitColor’ route, where :fruitName and :fruitColor are the URL params placeholders.

We can get the values of them from the req.params object.

Then, we return the extracted parameter values in the response object with res.json .

So if we make a GET request to /fruit/apple/green , we see:

{
    "fruitName": "apple",
    "fruitColor": "green"
}

returned as the response.

Categories
Express JavaScript Answers

How to Get Raw Request Body with Express?

To get raw request body in our Express app, we can add the raw body parsing function and set that as the value of the verify option of the middleware.

For instance, we can write:

const express = require('express')
const app = express()
const port = 3000
const bodyParser = require('body-parser');

const rawBodySaver =  (req, res, buf, encoding) =>{
  if (buf && buf.length) {
    req.rawBody = buf.toString(encoding || 'utf8');
  }
}

const options = {
  verify: rawBodySaver
};

app.use(bodyParser.json(options));

app.post('/', (req, res) => {
  console.log(req.rawBody)
  res.send('hello world')
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

We have the rawBodySaver function that gets the buf parameter, which has the raw request body buffer.

Then we call toString on it with the encoding and assign that to the req.rawBody property.

Next, we set the verify property of options to rawBodySaver and then use options as the argument for bodyParser.json to set rawBodySaver as the function to run when the request body is being parsed.

Then in the POST / route, we can get the raw request body from the req.rawBody property.