Categories
JavaScript JavaScript Basics

Why it’s time to use the async-await in JavaScript?

Asynchronous code is a regular part of JavaScript. As web apps get more complex, there’ll be more need for asynchronous code since JavaScript is single-threaded, and asynchronous code prevents the blocking of the main thread.

In this article, we’ll look at why async and await is the way to go for writing asynchronous code.

The Old Way to Write Promise Code

Before we look at async and await, we have to look at what it’s like in the old days.

In the olden days, we chain promises by writing something like the following:

Promise.resolve(1)  
  .then(val => Promise.resolve(2))  
  .then(val => Promise.resolve(3))  
  .then(val => Promise.resolve(4))  
  .then(val => Promise.resolve(5))  
  .then(val => Promise.resolve(6))

As we can see, we have to call then a lot and in each then call, we have to pass in a callback function to return the next promise. This is a pain because it’s very long-winded. If we want to do something like gathering the resolved values from each promise, then the code gets even longer.

For example, to gather the resolved values into an array, we have to write something like:

let vals = [];  
Promise.resolve(1)  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(2)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(3)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(4)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(5)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(6)  
  })  
  .then(val => {  
    vals.push(val);  
    console.log(vals)  
  });

Then we get [1, 2, 3, 4, 5, 6] as the value of vals.

As we can see, the number of lines of code exploded compared to the first example.

There’s lots of repetition and takes up lots of space in a file.

To deal with this, it’s time to move to the present with the async-await syntax for chaining promises.

Async and Await

To clean up the code in the example above, we can use async and await to do this.

We start a function declaration with async and we use the await keyword inside. await does the same thing as the then callbacks. It takes the resolved value of the promise and lets us do stuff with it.

With async and await, we can turn:

let vals = [];  
Promise.resolve(1)  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(2)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(3)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(4)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(5)  
  })  
  .then(val => {  
    vals.push(val);  
    return Promise.resolve(6)  
  })  
  .then(val => {  
    vals.push(val);  
    console.log(vals)  
  });

into:

(async () => {  
  const val = await Promise.resolve(1);  
  const val2 = await Promise.resolve(2);  
  const val3 = await Promise.resolve(3);  
  const val4 = await Promise.resolve(4);  
  const val5 = await Promise.resolve(5);  
  const val6 = await Promise.resolve(6);  
  const vals = [val, val2, val3, val4, val5, val6];  
  console.log(vals);  
})();

The await in the code above indicates that the code to the right of it returns a promise, and it’ll wait for the promise to be fulfilled until it moves on to the next one. Also, the resolved value can be assigned with the = and the variable or constant to the left of it.

The values can be gathered into an array at the end of the function and we can log it.

Even though this looks like synchronous code, async function can only return promises, so if we return vals, we’ll get a promise that resolves to the value of vals.

This means that:

const getVals = () => {  
  let vals = [];  
  Promise.resolve(1)  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(2)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(3)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(4)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(5)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(6)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(vals);  
    });  
}

is the same as:

const getValsAsyncAwait = async () => {  
  const val = await Promise.resolve(1);  
  const val2 = await Promise.resolve(2);  
  const val3 = await Promise.resolve(3);  
  const val4 = await Promise.resolve(4);  
  const val5 = await Promise.resolve(5);  
  const val6 = await Promise.resolve(6);  
  const vals = [val, val2, val3, val4, val5, val6];  
  return vals;  
};

We can use await on both and see what we get.

This block:

const getVals = () => {  
  let vals = [];  
  return Promise.resolve(1)  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(2)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(3)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(4)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(5)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(6)  
    })  
    .then(val => {  
      vals.push(val);  
      return Promise.resolve(vals);  
    });  
}

(async () => {  
  const values = await getVals();  
  console.log(values);  
})()

gets us [1, 2, 3, 4, 5, 6] from the console.log.

And:

const getValsAsyncAwait = async () => {  
  const val = await Promise.resolve(1);  
  const val2 = await Promise.resolve(2);  
  const val3 = await Promise.resolve(3);  
  const val4 = await Promise.resolve(4);  
  const val5 = await Promise.resolve(5);  
  const val6 = await Promise.resolve(6);  
  const vals = [val, val2, val3, val4, val5, val6];  
  return vals;  
};

(async () => {  
  const values = await getValsAsyncAwait();  
  console.log(values);  
})()

also gets us [1, 2, 3, 4, 5, 6] from the console.log. So they do exactly the same thing, just with much fewer lines of code.

Catching Errors

In the olden days we catch errors with the catch and the callback passed into it.

For example, we write something like:

Promise.resolve(1)  
  .then(val => console.log(val))  
  .catch(err => console.log(err));

Now we can use try...catch with async and await:

(async () => {  
  try {  
    const val = await Promise.resolve(1);  
  } catch (err) {  
    console.log(err);  
  }  
})();

This doesn’t save much space, but this may still come in handy in case of errors.

As we can see, async and await make code for chaining promises so much shorter. It’s been available since 2017, so it’s supported by most modern browsers. The time to use this to clean up our code is definitely now.

Categories
JavaScript Vue

Introduction to Vue.js Computed Properties and Watchers

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at Vue.js computed properties and watchers.

Computed Properties

To make more template expressions more concise and reusable, we can create computed properties to compute results from existing properties as their value changes.

We can define computed properties in a Vue instance by putting them in the computed property of the options object that we pass into the Vue constructor.

For example, we can write the following in src/index.js:

new Vue({  
  el: "#app",  
  data: {  
    message: "foo"  
  },  
  computed: {  
    spelledMessage() {  
      return this.message.split("").join("-");  
    }  
  }  
});

Then we can use it like any other field in our HTML template. So in index.html, we can write:

<!DOCTYPE html>  
<html>  
  <head>  
    <title>Hello</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head> <body>  
    <div id="app">  
      <p>{{message}}</p>  
      <p>{{spelledMessage}}</p>  
    </div>  
    <script src="./src/index.js"></script>  
  </body>  
</html>

We should then get:

foof-o-o

on our screen.

The spelledMessage method is a getter that’s used by Vue.js. It takes the returned value of it and then put it in place of {{spelledMessage}} .

Therefore, the name of the placeholder in the template must be the same as the name of the method that returns the value that we want in the computed object.

We can also get the value from the returned Vue instance as follows:

const vm = new Vue({  
  el: "#app",  
  data: {  
    message: "foo"  
  },  
  computed: {  
    spelledMessage() {  
      return this.message.split("").join("-");  
    }  
  }  
});

console.log(vm.spelledMessage);

We should see f-o-o logged from the console.log.

We can bind to computed properties in templates like any other property. Vue knows that vm.spelledMessage depends on vm.message, so the bindings will be updated when vm.message is updated.

The computed getter method doesn’t commit side effects, which makes it easy to test and understand.

Computed Caching vs Methods

One good feature of computed properties is that the result of it is cached.

There’s no caching for results returned from methods.

So instead of using methods, we should use computed properties for cases where we’re computing something from existing properties.

A computed property is only re-evaluated once a reactive property is updated.

For example, if we have:

const vm = new Vue({  
  el: "#app",  
  data: {  
    message: "foo"  
  },  
  computed: {  
    now() {  
      return Date.now();  
    }  
  }  
});

It’ll never update after its first computed since it doesn’t depend on any reactive property from the data property.

Without caching computed properties keep getting computed as reactive properties that they depend on change, which means the app gets slow as reactive properties that the computed property depends on are changing.

Computed vs Watched Property

Watch properties are useful for watching for changes in a property as the name suggests.

However, because of the caching feature of computed properties, we should use them as much as we can.

For instance, we can simplify the following:

new Vue({  
  el: "#app",  
  data: {  
    name: "Joe",  
    age: 1,  
    person: undefined  
  },  
  watch: {  
    name: {  
      immediate: true,  
      handler(newVal) {  
        this.person = `${newVal} - ${this.age}`;  
      }  
    },  
    age: {  
      immediate: true,  
      handler(newVal) {  
        this.person = `${this.name} - ${newVal}`;  
      }  
    }  
  }  
});

to:

new Vue({  
  el: "#app",  
  data: {  
    name: "Joe",  
    age: 1  
  },  
  computed: {  
    person() {  
      return `${this.name} - ${this.age}`;  
    }  
  }  
});

As we can see, the first example was much more complex. We have to set immediate to true in each property so that it’ll watch the initial value change. Then we have to define the value change handler for each reactive property.

Then in each handler, we have to set the person property so that we can combine name and age.

On the other hand, with computed properties, we only have one method which returns the fields combined in the way we want.

It’s much more convenient for us and the app that we create is also faster because of caching.

Computed Setter

We can also create a setter function for computed properties.

For example, we can write:

new Vue({  
  el: "#app",  
  data: {  
    name: "Joe",  
    age: 1  
  },  
  computed: {  
    person: {  
      get() {  
        return `${this.name} - ${this.age}`;  
      },  
      set(newValue) {  
        const [name, age] = newValue.split("-");  
        this.name = name.trim();  
        this.age = age.trim();  
      }  
    }  
  }  
});

The getter function returns the same thing as before, but now we also have a setter function.

The setter function splits the newValue, which has the computed value from the getter function, we split the result and set the result back to the corresponding reactive properties.

We can use a setter as follows. We can put the following in src/index.js:

new Vue({  
  el: "#app",  
  data: {  
    firstName: "Joe",  
    lastName: "Smith"  
  },  
  computed: {  
    name: {  
      get() {  
        return `${this.firstName} ${this.lastName}`;  
      },  
      set(newValue) {  
        const [firstName, lastName] = newValue.split(" ");  
        this.firstName = (firstName || "").trim();  
        this.lastName = (lastName || "").trim();  
      }  
    }  
  }  
});

And in index.html, we put:

<!DOCTYPE html>  
<html>  
  <head>  
    <title>Hello</title>  
    <meta charset="UTF-8" />  
    <script src="[https://cdn.jsdelivr.net/npm/vue/dist/vue.js](https://cdn.jsdelivr.net/npm/vue/dist/vue.js)"></script>  
  </head> <body>  
    <div id="app">  
      <p>{{name}}</p>  
      <input type="text" v-model="name" />  
    </div>  
    <script src="./src/index.js"></script>  
  </body>  
</html>

Then when we change the value in the input, we get the new values assigned back to the firstName and lastName fields with the setter.

Conclusion

We can use computed properties to compute values from existing properties.

Returned values from computed properties are cached to reduce the amount of computation required.

Computed properties can also have setters, where we can do things with the new values returned from the computed property getter.

Categories
Express JavaScript Nodejs

Configuring Express Multer Middleware and Checking File Information

Multer is a middleware that lets us process file uploads with our Express app.

In this article, we’ll look at the settings that we can change to upload files our way, and also check the file information.

Checking File Information

We can check the uploaded files’ information by looking at the req.file object for single file upload and the array entries of req.files for multiple file uploads.

These fields are available for each file:

  • fieldname — field name specified in the form
  • originalname — name of the file on the user’s computer
  • encoding — encoding type of the file
  • mimetype — MIME-type of the file
  • size — size of the file in bytes
  • destination — the folder where the file was saved on the server
  • filename — name of the file stored in the destination
  • path — the full path of the uploaded file
  • bufferBuffer object of the whole file

Options for File Upload

The multer function takes an options object that takes a variety of options.

We can do things like set the destination of the files and rename the files.

The following properties can be in the options object:

  • dest or storage — where to store the files
  • fileFilter — controls which files are accepted
  • limits — limits of the uploaded data
  • preservePath — keep the full path of the files instead of just the base name

Storage Options

DiskStorage

We can store files on disk by using the diskStorage method.

There’re 2 options available, destination and filename . They’re both functions that determine the destination where the file is saved and what to rename the file to respectively.

Each function takes the requestion object, file object and callback function. The callback function is called at the end of each function with the first argument being null .

The second argument is the destination that we want to save the file for the destination function and the filename that we want to rename the file to for the filename function.

For example, we can rename a file by keeping the original name and adding a timestamp to the end of the file as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const multer = require('multer');  
const storage = multer.diskStorage({  
  destination: (req, file, cb) => {  
    cb(null, './uploads/')  
  },  
  filename: (req, file, cb) => {  
    cb(null, `${file.originalname}-${+Date.now()}`)  
  }  
})
const upload = multer({ storage });  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.get('/', (req, res) => {  
  res.sendFile('public/index.html');  
});
app.post('/upload', upload.single('upload'), (req, res) => {  
  res.send('file uploaded')  
});
app.listen(3000, () => console.log('server started'));

MemoryStorage

memoryStorage stores files in memory as a Buffer object and doesn’t take any option.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const multer = require('multer');  
const storage = multer.memoryStorage();  
const upload = multer({ storage })  
const app = express();app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.get('/', (req, res) => {  
  res.sendFile('public/index.html');  
});
app.post('/upload', upload.single('upload'), (req, res) => {  
  console.log(req.file);  
  res.send('uploaded');  
});
app.listen(3000, () => console.log('server started'));

Then we get the buffer property in req.file with the content of the upload file as the value of it.

Upload Limits

The limits object specifies the size limits of the following optional properties:

  • fieldNameSize — maximum field name size. Defaults to 100 bytes
  • fieldSize — maximum field value size. Defaults to 1MB
  • fields — the maximum number of non-file fields. Defaults to Infinity
  • fileSize — maximum file size in bytes. Defaults to Infinity
  • files — maximum of file fields. Defaults to Infinity
  • parts — the maximum number of parts (fields and files). Defaults to Infinity
  • headerPairs — the maximum number of header key-value pairs to parse. Defaults to 2000.

This is useful for preventing denial of service attacks.

We can set the limits as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const multer = require('multer');  
const upload = multer({  
  limits: {  
    fieldSize: 1024 * 512,  
    fieldNameSize: 200  
  },  
  dest: './uploads/'  
});  
const app = express();app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.get('/', (req, res) => {  
  res.sendFile('public/index.html');  
});
app.post('/upload', upload.single('upload'), (req, res) => {  
  res.send('file uploaded')  
});
app.listen(3000, () => console.log('server started'));

We set the field size limit to 512 KB and field name size to 200 bytes in the code above.

Controlling the Files to Process

The fileFilter field is a function that lets us control which files should be uploaded and which should be skipped.

For example, we can throw an error if the file uploaded doesn’t have the MIME-type image/png and then handle the error in our route as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const multer = require('multer');  
const upload = multer({  
  fileFilter: (req, file, cb) => {  
    if (file.mimetype === 'image/png') {  
      cb(null, true);  
    }  
    else {  
      cb(new multer.MulterError('not a PNG'));  
    }  
  },  
  dest: './uploads/'  
})  
  .single('upload')  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.get('/', (req, res) => {  
  res.sendFile('public/index.html');  
});
app.post('/upload', (req, res) => {  
  upload(req, res, (err) => {  
    if (err instanceof multer.MulterError) {  
      res.send('file not uploaded since it\'s not a PNG');  
    }  
    else {  
      res.send('file uploaded');  
    }  
  })  
});
app.listen(3000, () => console.log('server started'));

First, we have the file type check by setting a function with the fileFilter function:

const upload = multer({  
  fileFilter: (req, file, cb) => {  
    if (file.mimetype === 'image/png') {  
      cb(null, true);  
    }  
    else {  
      cb(new multer.MulterError('not a PNG'));  
    }  
  },  
  dest: './uploads/'  
})  
  .single('upload')

Then in our /upload route, we have:

app.post('/upload', (req, res) => {  
  upload(req, res, (err) => {  
    if (err instanceof multer.MulterError) {  
      res.send('file not uploaded since it\'s not a PNG');  
    }  
    else {  
      res.send('file uploaded');  
    }  
  })  
});

to catch the MulterError and respond accordingly. If the file is a PNG, then it’s uploaded. Otherwise, an error is thrown and the error won’t be uploaded.

In either case, we send a response indicating if the file was uploaded.

Conclusion

Multer has lots of options for us to control how file upload is done. We can check the file type, set the destination, control how much we can upload, etc.

Also, we can catch errors in our routes by using the upload function inside our route handler instead of using it as a middleware.

We can also check for file information with req.file for single file upload and the req.files array for multiple file upload.

Finally, we can change where files are stored by changing the destination and storage type.

Categories
JavaScript JavaScript Basics

Scheduling Code Execution with JavaScript setTimeout and setInterval Functions

JavaScript has functions for running functions at a specified schedule time or interval. They’re the setTimeout and setInterval functions respectively.

setTimeout

setTimeout lets us run code after a specified time from the setTimeout function is called. It takes 2 arguments. The first is a callback function with code that we want to run. The second argument is the time in which the code in the callback function runs relative to the time that this function is called. This argument is a number in milliseconds.

We can use it as follows:

setTimeout(() => {  
  console.log('Hi');  
}, 3000)

The code above will log 'Hi' after 3 seconds, which is 3000 milliseconds.

We can also pass in a function reference or variable as follows:

function hi() {  
  console.log('Hi');  
}

setTimeout(hi, 3000)

Or we can write:

const hi = () => {  
  console.log('Hi');  
}

setTimeout(hi, 3000)

Notice that we just pass in the function name. This is because the function is to be run later, not immediately. Therefore, we want to pass in a function reference instead of calling it in the code.

We can pass in arguments to the callback function by specifying additional arguments after the second one. For example, we can write:

setTimeout((name, age) => {  
  console.log(`Hi ${name}. Your age is ${age}.`)  
}, 3000, 'Joe', 20);

After we run the code above, we should see 'Hi Joe. Your age is 20.’ since we passed in 'Joe' for name and 20 for age .

The setTimeout function returns an ID object which can be used to cancel the setTimeout operation with the clearTimeout function. We can use it as follows:

let timerId = setTimeout(() => {  
  console.log('Hi');  
}, 3000)

clearTimeout(timerId);

If we run the code above, we’ll see nothing since we cancelled the operation with the clearTimeout function.

Repeated setTimeout

We can use setTimeout like setInterval by nesting the callback function inside itself. For example to log 'Hi' every 3 seconds, we can write:

setTimeout(function hi() {  
  console.log('Hi');  
  setTimeout(hi, 3000);  
}, 3000)

Then we can cancel the repeated operations by:

let timerId;  
timerId = setTimeout(function hi() {  
  console.log('Hi');  
  timerId = setTimeout(hi, 3000);  
}, 3000)

clearTimeout(timerId);

The callback functions’ execution time is counted in the delay that we pass into the second argument, so the actual interval between the function runs is less than the delay we specified.

Zero Delay setTimeout

To run code immediately after the script is executed, we can specify 0 for the delay in the setTimeout function. For example, we can write:

console.log('1');  
setTimeout(() => {  
  console.log('3');  
})  
console.log('2');

Then we see that 1, 2 and 3 are logged in that order. This is because all the synchronous code is run first. Then the asynchronous code in the setTimeout ‘s callback function is run.

setInterval

The setInterval function lets us run code repeatedly at a specified time interval.

The arguments are the same as setTimeout .

We can use it as follows:

setInterval(() => {  
  console.log('Hi');  
}, 3000)

When we run the code above, we see the word 'Hi' logged every 3 seconds.

Like setTimeout , there’s a function to cancel the setInterval operation. There’s a clearTimeout function to cancel it.

setInterval returns an ID object which we can pass into the clearInterval method to cancel the operation.

For example, we can write:

let timerId = setInterval(() => {  
  console.log('Hi');  
}, 3000)

clearTimeout(timerId);

If we run the code above, we see that nothing is logged since the setInterval operation was cancelled immediately after it’s initiated.

We can pass in arguments to the callback function by specifying additional arguments after the second one. For example, we can write:

setInterval((name, age) => {  
  console.log(`Hi ${name}. Your age is ${age}.`)  
}, 3000, 'Joe', 20);

After we run the code above, we should see 'Hi Joe. Your age is 20.’ since we passed in 'Joe' for name and 20 for age.

Value of this

The value of this should be the window object and not undefined by default, even in strict mode.

For example, if we write:

setInterval(() => {  
  console.log(this)  
}, 3000);

We should get the window object logged every 3 seconds.

The setTimeout and setInterval functions are timer functions that let us run code that we want to schedule for a specified time or an interval respectively.

We do this by passing in a callback function which runs the code we want to delay or run repeatedly. Then we specify the delay or interval in milliseconds.

To pass in arguments to the callback function, we can specify additional arguments after the second argument in both functions.

The timer isn’t always exactly because of CPU issues like it being overloaded, or lots of background processes are running, or the CPU is throttled.

Categories
Express JavaScript Vue

Guide to the Express Request Object — Queries and Cookies

The request object lets us get the information about requests made from the client in middlewares and route handlers.

In this article, we’ll look at the properties of Express’s request object in detail, including query strings, URL parameters, and signed cookies.

Request Object

The req parameter we have in the route handlers above is the req object.

It has some properties that we can use to get data about the request that’s made from the client-side. The more important ones are listed below.

req.originalUrl

The originalUrl property has the original request URL.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.get('/', (req, res) => {  
  res.send(req.originalUrl);  
})
app.listen(3000);

Then when we have the request with query string /?foo=bar , we get back /?foo=bar .

req.params

params property has the request parameters from the URL.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

app.get('/:name/:age', (req, res) => {  
  res.json(req.params)  
})

app.listen(3000, () => console.log('server started'));

Then when we pass in /john/1 as the parameter part of the URL, then we get:

{  
    "name": "john",  
    "age": "1"  
}

as the response from the route above.

req.path

The path property has the path part of the request URL.

For instance, if we have:

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

app.get('/:name/:age', (req, res) => {  
  res.send(req.path);  
})

app.listen(3000);

and make a request to /foo/1 , then we get back the same thing in the response.

req.protocol

We can get the protocol string with the protocol property.

For example, if we have:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.get('/', (req, res) => {  
  res.send(req.protocol);  
})

app.listen(3000);

Then when we make a request through HTTP we get backhttp .

req.query

The query property gets us the query string from the request URL parsed into an object.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {  
  res.json(req.query)  
})

app.listen(3000, () => console.log('server started'));

Then when we append ?name=john&age=1 to the end of the hostname, then we get back:

{  
    "name": "john",  
    "age": "1"  
}

from the response.

req.route

We get the current matched route with the route property.

For example, we can use it as follows:

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

app.get('/', (req, res) => {  
  console.log(req.route);  
  res.json(req.route);  
})

app.listen(3000);

Then we get something like the following from the console.log :

Route {  
  path: '/',  
  stack:  
   [ Layer {  
       handle: [Function],  
       name: '<anonymous>',  
       params: undefined,  
       path: undefined,  
       keys: [],  
       regexp: /^\/?$/i,  
       method: 'get' } ],  
  methods: { get: true } }

req.secure

A boolean property that indicates if the request is made with via HTTPS.

For example, given that we have:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.get('/', (req, res) => {    
  res.json(req.secure);  
})

app.listen(3000);

Then we get false if the request is made via HTTP.

req.signedCookies

The signedCookies object has the cookie with the value deciphers from the hashed value.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const cookieParser = require('cookie-parser');  
const app = express();  
app.use(cookieParser('secret'));
app.get('/cookie', (req, res, next) => {  
  res.cookie('name', 'foo', { signed: true })  
  res.send();  
})

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

app.listen(3000);

In the code above, we have the /cookie route to send the cookie from our app to the client. Then we can get the value from the client and then make a request to the / route with the Cookie header with name as the key and the signed value from the /cookie route as the value.

For example, it would look something like:

name=s%3Afoo.dzukRpPHVT1u4g9h6l0nV6mk9KRNKEGuTpW1LkzWLbQ

Then we get back foo from the / route after the signed cookie is decoded.

req.stale

stale is the opposite of fresh . See [req.fresh](https://expressjs.com/en/4x/api.html#req.fresh) for more details.

req.subdomains

We can get an array of subdomains in the domain name of the request with the subdomains property.

For example, we can use it as follows:

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

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

app.listen(3000);

Then when we make a request to the / route, we get something like:

["beautifulanxiousflatassembler--five-nine"]

req.xhr

A boolean property that’s true is X-Requested-With request header field is XMLHttpRequest .

For example, we can use it as follows:

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

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

app.listen(3000);

Then when we make a request to the/ route with the X-Requested-With header set to XMLHttpRequest , we get back true .

Conclusion

There’re many properties in the request object to get many things.

We can get signed cookies with the Cookie Parser middleware. Query strings and URL parameters can access in various form with query , params , and route properties.

Also, we can get parts of the subdomain with the subdomains property.