Categories
Node.js Tips

Node.js Tips — Promises, CSV to JSON, Watching Files

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.

Handle Errors Thrown by require() in Node.js

We can use try-catch to catch errors thrown by require .

For instance, we can write:

try {
  require('./app.js');
}
catch (e) {
  console.log(e);
}

We just call require in try then we can catch the error in catch .

How to use async/await with Streams

We can use async and await with streams by creating a promise with the stream with the Promise constructor.

For instance, we can write:

const fd = fs.createReadStream('/foo.txt');
const hash = crypto.createHash('sha1');
hash.setEncoding('hex');
fd.pipe(hash);

const readHash = new Promise((resolve, reject) => {
  hash.on('end', () => resolve(hash.read()));
  fd.on('error', reject);
});

Then we can use readHash in an async function by writing:

`(async function() {
  const sha1 = await` readHash`;
  console.log(sha1);
}());`

Promise Retry Design Patterns

We can retry a promise by delaying the promise.

For instance, we can write:

const retry = (fn, retries=3, err=null) => {
  if (!retries) {
    return Promise.reject(err);
  }
  return fn().catch(err => {
    return retry(fn, (retries - 1), err);
  });
}

fn is a function that returns a promise.

We retry as long as we haven’t exhausted the retries.

If the promise rejected by fn is rejected, then we call catch by passing in a callback to call retry with retries subtracted by 1.

We do that until retries reaches 0, then the retries are exhausted.

We Don’t Need .catch(err => console.error(err)) When Writing Promise Code

We don’t need to write .catch(err => console.error(err)) since promise rejections are already logged by Node.js.

We would know that an error happened even if we don’t have this line.

How to convert CSV to JSON in Node.js

We can use the csvtojson library to convert CSV to JSON.

To install it, we run:

npm install --save csvtojson

Then we can use it by writing:

const csv = require("csvtojson");

const readCsv = (csvFilePath) => {
  csv()
    .fromFile(csvFilePath)
    .then((jsonArrayObj) => {
       console.log(jsonArrayObj);
     })
}

We can read small files by passing in the csvFilePath to the fromFile method.

It returns a promise.

We get the converted result in the jsonArrayObj parameter.

We can also read the content from a stream and then get the JSON.

For instance, we can write:

const readFromStream = (readableStream) => {
  csv()
    .fromStream(readableStream)
    .subscribe((jsonObj) => {
       console.log(jsonObj)
    })
}

We call the fromStream method to get data from a stream.

Then we call subscribe with a callback to read the object.

Also, we can use fromFile with async and await since it returns a promise:

const csvToJson = async (filePath) => {
  const jsonArray = await csv().fromFile(filePath);
}

It can also be used on the command line.

For example, we can run it directly by running:

npm install -g csvtojson
csvtojson ./csvFile.csv

Edit Node App Files on the Server Without Restarting Node.js and See the Latest Changes

We can use a package like Node-Supervisor to watch for file changes and restart the Node app automatically.

To install it, we run:

npm install supervisor -g

Then we can run our program with Node-Supervisor by running:

supervisor app.js

Likewise, we can use Nodemon to do the same thing.

We can install it by running:

npm install -g nodemon

to install it globally.

Or we can install it by running:

npm install --save-dev nodemon

to install it as a project’s dev dependency.

Then we can run:

nodemon app.js

to run our app.

Chain and Share Prior Results with Promises

To share prior results with promises, we can chain them with then .

For instance, we can write:

makeRequest(url1, data1)
  .then((result1) => {
    return makeRequest(url2, data2);
  })
  .then((result2) => {
    return makeRequest(url3, data3);
  })
  .then((result3) => {
     // ...
  });

We get the resolved results from the previous promise in the then callbacks.

To make this shorter, we can use async and await to do the same thing:

const makeRequests = async () => {
  //...
  const r1 = await makeRequest(url1, data1);
  const r2 = await makeRequest(url2, data2);
  const r3 = await makeRequest(url3, data3);
  return someResult;
}

Conclusion

We can put streams in promises.

Also, we can watch for code file changes and restart our Node app with various programs.

The csvtojson library lets us convert CSV to JSON.

Promises can be retried by invoking it again.

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 *