Skip to content
Advertisement

TypeError: fs.createReadStream is not a function

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.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement