I prefer to use promises rather than callbacks so I’ve used util.promisify
.
`use strict`; const util = require(`util`), request = util.promisify(require(`request`)), fs = require(`fs`).promises; module.exports = async (message, api) => { const end = api.sendTypingIndicator(message.threadID); const data = await request({ url: `https://api.thecatapi.com/v1/images/search`, followAllRedirects: true }); const [json] = JSON.parse(data.body); console.log(fs); const image = await request(json.url); await fs.writeFile(`kitty.png`, image.body, `binary`); const attachments = {attachment: fs.createReadStream(`kitty.png`)}; await fs.unlink(`kitty.png`); end(); return attachments; };
I’ve received TypeError: fs.createReadStream is not a function
at const attachments = {attachment: fs.createReadStream('kitty.png')};
line. How can I solve that?
Advertisement
Answer
fs.promises
is not a superset of fs
. While it replaces some methods on fs
with methods of the same core name that return a promise, it does not have everything on it that the plain fs
has.
createReadStream()
is a method on the regular require('fs')
object, not on require('fs').promises
.
This is why it is not recommended that you do this:
fs = require('fs').promises;
Because then it misleads everyone, including yourself into thinking that fs
is the core nodejs fs module. It’s not.
Instead, I would recommend this:
const util = require('util'), request = util.promisify(require('request')), fs = require('fs'), fsp = fs.promises;
Then, you can use both fs
and fsp
as appropriate including fs.createReadStream()
.
Yes, this does seem a bit untidy. Perhaps the fs
module conversion to promises is only partially complete and someday you can use fs.promises
as a full replacement – I don’t really know what the folks working on that module intend. For now, you have to use both versions to get access to full functionality.
Also, be careful about util.promisify(require('request'))
. The request function does not use the standard asynchronous callback signature (err, result)
since it passes three arguments to the callback (err, response, body)
, not the usual two. There are request derivative modules that are already promisified (request-promise
and request-promise-native
) that are fully ready to use with promises.
Also, the request()
module has been deprecated now (as of 2020 and will not get any more new features) and a list of alternatives (all of which support a promise interface) is here.