Categories
Node.js Tips

Node.js Tips — Modules, Request Bodies, Reading Lines, and More

Spread the love

Like any kind of apps, there are difficult issues to solve when we write Node apps.

In this article, we’ll look at some solutions to common problems when writing Node apps.

How to Include Functions from Other Files

We can include functions from other files if we export the function from a module and then import them.

For example, we can write:

fns.js

module.exports = {
  foo() {
    //...
  }
};

module.exports indicates that we’re exporting the properties inside.

Then we can import it by writing:

const `fns` = require('./`fns`');
`fns.foo();`

We use the require keywords to import the fns.js module.

We don’t need the file extension.

Using Node.js require vs. ES6 import/export

require is the most versatile way to import modules and it’s supported by all versions of Node.

ES6 imports and exports are supported natively only by the most recent versions of Node.

Therefore, require is still the best bet until our apps are running on the latest version of Node.

Sending Command-Line Arguments to npm script

We can send command line arguments to an NPM script by using the -- characters.

For example, if we have the following in package.json :

"scripts": {
  "server": "node server.js"
}

Then we can run:

npm run server -- --port=1234

Retrieve POST Query Parameters in an Express App

We can retrieve POST query parameters in an Express app by installing the body-parser package.

To install it, we run:

npm install --save body-parser

For example, we can write:

const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));

bodyParser.json() will parse JSON payloads.

And bodyParser.urlencoded will parse URL encoded payloads.

‘Can’t set headers after they are sent to the client’ Error

We should make sure that we don’t send a response more than once in our app.

For instance, we should write:

const foo = (request, response, next) => {
  request.params = {
    a: "b"
  };
  next();
};

const bar = function(request, response, next) => {
  response.setHeader("Content-Type", "text/html");
  response.write("hello world");
  response.end();
};

app.use(foo);
app.use(bar);

Anything that modifies the response should be placed last.

This way, we don’t send the response more than once.

Anything that calls next shouldn’t modify the response so that we won’t call any middleware that does send the response after it.

Convert an Existing Callback API to Promises

We can convert any async callback to a promise with the Promise constructor.

For instance, we can write:

const run = () => {
  return new Promise((resolve, reject) => {
    //...
    resolve();
  });
}

We return a promise in our run function so we can use it with async and await or then .

Also, we can use the util package’s promisify method to convert functions that take Node style callbacks to return a promise.

For instance, we can write:

const fs = require('fs');
const util = require('util');

const readFile = util.promisify(fs.readFile);

(async () => {
  const data = await `readFile('/foo.txt');
  //...
})();`

We convert the async readFile method to a promise by using the util.promisify method.

Then we get the data from reading the file with await .

Read a File One Line at a Time

To read a file one line at a time, we can use the readline module.

For example, we can write:

const fs = require('fs');
const readline = require('readline');

const readLineByLine = async () => {
  const fileStream = fs.createReadStream('foo.txt');

  const rl = readline.createInterface({
    input: fileStream,
    crlfDelay: Infinity
  });

  for await (const line of rl) {
    console.log(line);
  }
}

readLineByLine();

We call createInterface to get an iterator with the lines, then we use the for-await-of loop to loop through the lines.

Also, we can create a read stream by writing:

const readline = require('readline');

readline.createInterface({
  input: require('fs').createReadStream('file.in')
});

lineReader.on('line', (line) => {
  console.log(line);
});

We use the createInterface like the last example, but we call on to listen to the line event which has the line that’s read.

Conclusion

We can export and import files to include functions from other JavaScript files.

Reading a file one line at a time can be done with the readline library.

Also, we should make sure that we don’t send a response more than once in our Express app.

The body-parser package lets us parse request payloads in an Express app.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *