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.