0

I'm reading files with Node in a 4 step process. Each step has to wait for the resolution of the function it calls. It seems like a very simple task to accomplish, but the async functions are not awaiting the result of their variable definitions ( i.e. even though the variable 'finish' is dependent on the variable processData which is awaiting an async function, it fires anyway.

I'm guessing I have a butchered understanding of the fundamental behavior if my conclusions aren't correct. And I know there are a ton of threads with this issue, but I would appreciate some help. Oh, and if I log the results from the fs.readFile method in its callback, the data shows up. But the data is returned undefined from that block. Code below:

async function formatData(){ 
    const processData = await getFiles()
    const finish = await printData(processData)
}


async function getFiles(){
    const checkFile = await getFileData('./csvs/checkfile_for_node_test.csv')
    const scheduleFile = await getFileData('./csvs/schedules_for_node_test.csv')

    console.log('returning files')
    return {checks: checkFile, schedules: schedFile}
}

async function getFileData(file){
     const fileData = await fs.readFile(file, (err, data) => data ) 
     console.log(`file data: ${fileData}`)
     return fileData
}

function printData(data){
    console.log(data)
    return data
}

formatData()
4
  • You are running await on printData which is not an async function. Please make it async and check. You can also simply remove async from printData call. Commented Jul 24, 2020 at 18:05
  • 1
    Are you using a Promisified version of readFile? It doesn't look that way, in which case await fs.readFile(...) won't do what you hope. Commented Jul 24, 2020 at 18:07
  • So you're getting file data: undefined in your logs, right? Commented Jul 24, 2020 at 18:47
  • That's right. User below solved. Commented Jul 30, 2020 at 22:24

2 Answers 2

2

I believe you are missing promise from getFileData function. Below is the modified code

const fs = require("fs");

async function formatData() {
  const processData = await getFiles();
  const finish = await printData(processData);

  console.log(finish);
}

async function getFiles() {
  const checkFile = await getFileData("./hello.txt");
  const scheduleFile = await getFileData("./world.txt");

  console.log("returning files");
  return { checks: checkFile, schedules: scheduleFile };
}

async function getFileData(file) {
  return new Promise((res, rej) => {
    fs.readFile(file, (err, data) => {
      if (err) rej(err);
      console.log(`file data: ${data}`);
      res({ fileData: data });
    });
  });

  return fileData;
}

async function printData(data) {
  console.log(data);
  return data;
}

formatData();
Sign up to request clarification or add additional context in comments.

3 Comments

Don't forget to put the resolve() call in an else statement
Thanks, @Bergi, I have only renamed the resolve to res, in above code. Is it still incorrect?
No, it's not correct. You're still calling the console.log and the res even if there was an error.
1

I don't know if the code you provided is the actual code, but there seems to be a lot of issues. I will break down them one by one for you:

  1. When you are calling formatData you should use await keyword before it because it is an async method.

  2. At the last line of getFiles method, you mistakenly placed schedFile instead of scheduleFile.

  3. You are trying to use fs.readFile with await. It does not work that way. You have to either promisify it or use readFileSync.

All put together in code:

async function formatData(){ 
    const processData = await getFiles()
    const finish = await printData(processData)
}


async function getFiles(){
    const checkFile = await getFileData('./csvs/checkfile_for_node_test.csv')
    const scheduleFile = await getFileData('./csvs/schedules_for_node_test.csv')

    console.log('returning files')
    return {checks: checkFile, schedules: scheduleFile}
}

async function getFileData(file){
     const readFileAsync = promisify(fs.readFile); 
     const fileData = await readFileAsync(file, { encoding: 'utf-8' });
     console.log(`file data: ${fileData}`)
     return fileData
}

function printData(data){
    console.log(data)
    return data
}

window.addEventListener('load', async function () {
   await formatData();
});

I hope it works.

2 Comments

4. printData is synchronous, there's no reason to await the call
"When you are calling formatData you should use await keyword" - not necessarily, it appears to be the top-level call. What's more important is to handle errors from it, using e.g. formatData().catch(console.error). Btw, this is node.js code, which doesn't have a window and there are no load events to listen for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.