Node.js Tips — Modules, Request Bodies, Reading Lines, and More
Tags: node, webdev, programming, javascript
Published: 2021-01-26 03:02:40

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


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.