node.jsterminalcommand-line-interfaceinquirerjs

Weird behaviour of the Inquirer package printing multiple times


I am trying to create a cli tool which downloads packages (internally uses npm) and create files. I am using inquirer to ask for user input on what database they'd like to add but the output from inquirer is not what I expected it to be.

This is my code (I have skipped the imports and other boilerplate code):

const questions = [
  {
      type: 'list',
      name: 'option',
      message: 'Choose an option:',
      choices: [
          'MongoDB (mongoose)',
          'Firebase',
          'PostgreSQL',
          'MySQL',
          'Redis'
      ],
  }
];

argv.command({
  command: 'create-node-app',
  describe: 'Creates a basic node project with usual files',
  builder: {
    y: {
      describe: "Use default values to build the package.json",
      demandOption: false
    }
  },
  handler: async (argv) => {
    let packages = [];
    let dependencies = '';
    const execa = util.promisify(exec);

    async function setup(jsonFile) {
      // no libraries are given, add default librariesthen create the file
      if (argv._.length == 1) {
        console.log(chalk.yellow("Note: Predefined libraries will be added to the package.json"));
        
        console.log(chalk.yellow("Please select the database you'd like to connect to your application: "));
        // cliSelect({
        //   values: ["MongoDB", "PostgreSQL", "Firebase", "Redis", "MySQL"],
        //   valueRenderer: (value, selected) => {
        //     if(selected) {
        //       return chalk.blue(value)
        //     }
        //     return value;
        //   }
        // }).then(res => console.log("The result/value:", res, "\n"))
        await inquirer.prompt(questions).then((answers) => {
          console.log(chalk.green(`The package ${answers.option} will be downloaded`));
        }).catch(err => {
          console.log("There was an error");
        })

        packages.push("express", "ejs", "dotenv", "cors", "body-parser");
        dependencies = await installPackages(packages);
        renderTemplate("./bin/templates/_index.ejs", "./", jsonFile.main || "index.js", {path: "/public/index.html"});
      } else if(argv._.length > 1) {
        //get all the arguments after the first ('create-node-app') argument to get all packages
        packages = argv._.slice(1);
        dependencies = await installPackages(packages);
        createFile("./", jsonFile.main || "index.js", "//This is the server file");
      }
      createFolder("./", "public", rl);
      renderTemplate("./bin/templates/_indexhtml.ejs", "./public/", "index.html", jsonFile);
      renderTemplate("./bin/templates/_styles.ejs", "./public/", "styles.css", "");
      renderTemplate("./bin/templates/_app.ejs", "./public/", "app.js", "");
    }
    
    //if the y flag is used
    let jsonFile;
    if(argv.y) {
      (await execa("npm init -y")).stdout;
    } else {
      // await execa("npm init");
      execSync('npm init', {stdio: 'inherit'})
    }
    console.log("The package.json file has been created");
    jsonFile = JSON.parse(fs.readFileSync("./package.json"))
    setup(jsonFile);

    createFile("./", ".env", "");
    createFile("./", ".gitignore", "node_modules\n.env");
    console.log("Done");
  }
});

This is what the output looks like when I run the command create create-node-app -y (This runs the npm init -y command to make the default package.json library and installs predefined packages but asks what database to include): When I run the above command

When I press the arrow keys to select a database:
enter image description here

When I press "enter" to select an option:
enter image description here

As you can see I also tried using cli-select package but I faced the same issue so I am not using the package correctly but I don't know where am I missing?

Other functions like creatFolder, createFile, and renderTemplate do exactly what the name says. (renderTemplate renders an ejs template)


Solution

  • For anyone in the future facing the same issue.

    I had initialized the readline package before and was also using the inquirer package. All I had to do is to remove the readline package since it was using the terminal along with inquirer which lead to the above issue.