lapots
lapots

Reputation: 13395

import async function from the module

I have a function that looks like this

let fileCache = {};
async function generateFromFile(fullPath) {
    if (!fileCache[fullPath]) {
        let jsonResource = await fs.readFile(fullPath);
        fileCache[fullPath] = JSON.parse(jsonResource);
    }
    return fileCache[fullPath];
}

When I use it in the same module like this

await generateFromFile('myfile.json');

it works fine.

I created a separate file, put the function there and exported it like this

let fileCache = {};
async function generateFromFile(fullPath) {
    if (!fileCache[fullPath]) {
        let jsonResource = await fs.readFile(fullPath);
        fileCache[fullPath] = JSON.parse(jsonResource);
    }
    return fileCache[fullPath];
}

module.exports = {
    generateFromFile: generateFromFile
}

I imported it like this

const utils = require('../util/utils.js');

and wanted to use like await utils.generateFromFile('myfile.json'); but it fails with the error

TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined

What is the problem?

Upvotes: 1

Views: 1193

Answers (2)

SoulKa
SoulKa

Reputation: 195

Are you sure that your newly created file is in the relative directory ../util/utils.js? Your export looks fine. Maybe try to print out the imported utils object to see what you actually imported.

EDIT: You are also passing relative filenames to your function which is now in a different diretory than before. When accessing fs.readFile(fullPath) it tries to read the file inside the directory "util/". You should call your function with a full filepath like util.generateFromFile(path.join(__dirname, "myfile.json")) using the path node package.

EDIT 2: Like Raeesaa state you are using fs.readFile wrong. It does not return a Promise but expects a callback. To is it with await you have to promisify it like so:

const fs = require("fs");
const { promisify } = require("util");
const readFileAsync = promisify(fs.readFile);

let fileCache = {};
async function generateFromFile(fullPath) {
    if (!fileCache[fullPath]) {
        let jsonResource = await readFileAsync(fullPath);
        fileCache[fullPath] = JSON.parse(jsonResource);
    }
    return fileCache[fullPath];
}

module.exports = {
    generateFromFile: generateFromFile
}

EDIT 3: If you only import JSON files you can do it by using require. Internally, require has also a cache so imports are only executed once. You can import JSON files as objects like so: const obj = require("myfile.json");

Upvotes: 2

Boris Kukec
Boris Kukec

Reputation: 721

How did you import your fs module. To use readFile with await your should either write fs.promise.readFile or import fs as import { promises as fs } from 'fs'

Upvotes: 2

Related Questions