Search code examples
javascriptnode.jsfsinquirer

How to wait inquirer answer to be processed (by fs.writeFile) before continuing asynchronously


So I have this asynchronous function with inquirer and fs.writeFile inside

(async () => {

...

  if (process.env.IG_USERNAME && process.env.IG_PASSWORD) {
    console.log(`Used as ${chalk.green(process.env.IG_USERNAME)}`);
  } else {
    console.log(`\nInstagram account data is not yet put in \nInputting in...`);

    await inquirer.prompt(questions).then((answers) => {
      let file = `IG_USERNAME=${answers.username}\nIG_PASSWORD=${answers.password}\n#ONLINE_MODE=true`;
      fs.writeFile(".env", file, (err) => {
        if (err) console.log("Something went wrong..");
        else console.log(`Used as ${chalk.green(process.env.IG_USERNAME)}`);
      });
    });
  }

  await login();

...

})();

the login(); function needs the .env variable, i input it using inquirer but the login(); function get executed before the inquirer answer get processed.

What should I do to make the login(); waits until the fs.writeFile is finished?


Solution

  • Generally either use .then() or await with promises, not both together. And login() is getting executed before because the promise is getting resolved via .then().

    And there is no promise returned to await for before calling login().

    Solution 1: The quick fix is to resolve await login(); inside the callback of fs.writeFile, but then login()'s error would have to be handled as well, which just makes the code more verbose to begin with.

    const answers = await inquirer.prompt(questions);
    let file = `IG_USERNAME=${answers.username}\nIG_PASSWORD=${answers.password}\n#ONLINE_MODE=true`;
    fs.writeFile(".env", file, async (err) => {
      if (err) console.error("Error:fs.writeFile()::", err);
      else console.log(`Used as ${chalk.green(process.env.IG_USERNAME)}`);
      try {
        await login();
      } catch (e) {
        console.error("Error::login():", e);
      }
    });
    

    Solution 2: util.promisify with Node >= V8

    Make the fs.writeFile to a promise.

    const fs = require("fs");
    const { promisify } = require("util");
    const promisedWriteFile = promisify(fs.writeFile);
    
    try {
      const answers = await inquirer.prompt(questions);
      let file = `IG_USERNAME=${answers.username}\nIG_PASSWORD=${answers.password}\n#ONLINE_MODE=true`;
      await promisedWriteFile(".env", file);
      await login();
    } catch (error) {
      console.error("Any error::", error);
    }
    

    Solution 3: fs Promises API with Node >= V10

    try {
      const answers = await inquirer.prompt(questions);
      let file = `IG_USERNAME=${answers.username}\nIG_PASSWORD=${answers.password}\n#ONLINE_MODE=true`;
      await fs.promises.writeFile(".env", file);
      await login();
    } catch (error) {
      console.error("Any error::", error);
    }