JustCurious
JustCurious

Reputation: 830

TypeError: "FunctionName" is not a function during async and await

I am new to javascript and trying to understand Async and Await. This is the code which I have written which tries to read from a file and if the file is not found it rejects.

async function getFileAsString(path) {
    if (!path) {
        throw "you need to give a path!"
    }

    const fileContent = await fileCheck(path);
    console.log(fileContent)
}

var fileCheck = function(path) {
    return new Promise(function(resolve, reject) {
        if (fs.readFileAsync(path, "utf-8")) {
            resolve("File found!")
        } else {
            reject("File not found!!")
        }
    })
}

I am getting a error saying "TypeError: fileCheck is not a function during async and await. I cant figure out the reason. Can someone please help me with this? Thank you.

Upvotes: 2

Views: 5601

Answers (3)

Asleepace
Asleepace

Reputation: 3745

I was doing this the other day, there are a couple things that are going wrong above. Try something like this:

const fs = require('fs');

class FileManager {
  async getFileAsString(path) {
    if (!path) {
        throw "you need to give a path!"
    }

    const fileContent = await this.fileCheck(path);
    console.log(fileContent)
  }

  fileCheck(path) {
    return new Promise(function(resolve, reject) {
      fs.readFile(path,'utf8',(err, result) => {
        if (err) reject(err);
        else resolve(result);
      });
    })
  }
}

// Example usage
const fileManager = new FileManager();
fileManager.getFileAsString('./release.js');

It is a little bit of extra code, but putting it in a class prevents the hoisting issues mentioned above. Also I noticed last week when I was doing this, async / await was behaving weirdly when not used with a class, not sure what that was about...

[EDIT]

Also there is a readFileSync method that already does this, have a look at this thread:

Difference between readFile and readFileSync

Upvotes: -2

Patrick Roberts
Patrick Roberts

Reputation: 51916

Just wrap the callback-style asynchronous function fs.readFile() using util.promisify():

var readFile = util.promisify(fs.readFile);

async function getFileAsString(path) {
    // `readFile()` will throw proper error if `path` is invalid
    const fileContent = await readFile(path, 'utf-8')
    console.log(fileContent)
    return fileContent
}

Upvotes: 3

Jonas Wilms
Jonas Wilms

Reputation: 138437

There are a few problems in your code:

1)

 fs.readFileAsync(path, "utf-8")

does not exist. Just omit the Async. readFile is async by default.

2)

 if(fs.readFile(path, "utf-8"))

As noticed above, readFile is async, that means that it does not return anything (= undefined) but rather calls the passed callback somewhen. So you either use the sync version:

 try {
   fs.readFileSync(path, "utf-8")
   // ... All fine
 } catch(error){
   // File corrupted / not existing
 }

or you check in the callback:

 fs.readFile(path, "utf-8", function callback(error, data){
   if(error) /*...*/;
 });

3) Using the function expression as such:

var checkFile = function(){}

is a bad idea as it introduces hoisting problems and so on.


 function checkFile(path){
   return new Promise((res, rej) => {
      fs.readFile(path, "utf-8", function callback(err, data){
         err ? rej(err) : res(data);
      });
   });
}

Upvotes: 4

Related Questions