JShoe
JShoe

Reputation: 3428

How to properly nest inquirer prompts?

Summary

I'm working on a project for school that requires us to use Inquirer to help users navigate an SQL database. I've boiled down my question to a minimum example.

Basically, my main init() function continuously loops through an Inquirer prompt asking them what they want to do. I take their response, plug it into a switch statement, and perform the correct action based on the user's choice. Easy.

But then when I try to again await the call from the second prompt, the main "action" prompt actually triggers again, where the prompts are populating each other within the console. I don't really know how to describe it, but it's not what I expect.

Code

import inquirer from "inquirer";

import { employeeQuestions } from "./lib/questions.js";

const prompt = inquirer.prompt;

const actionQuestions = [{
    name: "action",
    type: "list",
    message: "Welcome! What would you like to do?",
    choices: [
        "View all Employees",
        "Add an Employee",
        "Exit"
    ]
}];

// This function handles the action chosen by the user in the main loop
const performAction = async (action) => {
    switch (action) {
        case "View all Employees":
            console.log("Not yet implmented...");
            break;
        // HERE IS WHERE THINGS BREAK DOWN
        case "Add an Employee":
            let employeeData = await prompt(employeeQuestions); // Grab the employee data by awaiting prompt
            console.log(employeeData); // Console out the data
            break;
        default:
            break;
    }
}

// Main logic flow
 const init = async () => {
    let action;

    // While the user has not chosen to exit...
    while (action != "Exit") {
        action = (await prompt(actionQuestions)).action; // Get their choice by awaiting a prompt
        performAction(action); // Perform that chosen action
    }
}

init();

Expectation:

I would expect the program to pause at let employeeData = await prompt(employeeQuestions); and not proceed in that switch/case block until the user has responded.

Observation:

Instead, both prompts begin running at the same time.

Moving forward

Conclusion

I'm missing something obvious about promises / async/await. I'm in a coding BootCamp that makes use of Inquirer repeatedly, and I get stuck in the same place every time. Please send help, or at least caffeine.

Upvotes: 1

Views: 1959

Answers (1)

Hopefully I'm not late, I will try to enlighten you as much as possible on the easiest and most effecient way to use inquirer (at the least for me).

So first of all i like to organize all of my questions in one file, so i don't think you would need to have to separate files filled with questions (hence employeeQuestions) <-- this will distract you when u need to find a specific quesiton. Here's a sample of my questions.js:

const inquirer              = require('inquirer');
inquirer.registerPrompt('search-list', require('inquirer-search-list'));

module.exports = () => {
    return {
        redisURIQuestion : () => {
            const question = [
                {
                    name: 'redisURI',
                    type: "input",
                    message: 'Enter your Redis URI:',
                    default: 'redis://127.0.0.1:6379'
                }
            ]
            return inquirer.prompt(question)
        
        },

        cortexPrefixQuestion : () => {
            const question = [
                {
                    name: 'cortexPrefix',
                    type: "input",
                    message: 'Enter your Cortex Prefix:',
                    default: 'none'
                }
            ]
            return inquirer.prompt(question)
        
        },
    }

Now all you need is just refernce the question you want to use:

const questions             = require('./questions')()

const { redisURI }      = await questions.redisURIQuestion()
const { cortexPrefix }  = await questions.cortexPrefixQuestion()

and of course you can use the output with conditionals if you need to check something first:

const { operationMode } = await questions.operationModeQuestion()

if(operationMode === 0){
  const { NODE } = await questions.nodesQuestion()
} else if(operationMode === 1){
  const { HOST } = await questions.hostsQuestion()
}

I have been building complex CLI apps using this concept without facing any issues hopefully this was helpful.

Upvotes: 0

Related Questions