Inquirer.js: Timeout/cancel current prompt?

Created on 1 Feb 2017  路  5Comments  路  Source: SBoudrias/Inquirer.js

I have a scenario where I need to prompt for some input (in my case a yes/no confirm call). However, if I don't get an answer within 30 seconds I need to assume yes and move on.

I can do this by creating a second promise that just completes after 30 seconds and using Promise.race so that I'm sure to complete within my timeout. However, at that point the original prompt is still open and waiting for keyboard input.

This is resulting in annoying extra text being output after the timeout, and messed up keyboard input. In particular, in my simplified test even though the process is done, it's still waiting for keyboard input. Is there a better way to do this timeout?

Sample code:

const inquirer = require('inquirer');

let p1 = inquirer.prompt([
  {
    type: 'confirm',
    name: 'result',
    message: 'Do it?',
    default: true
  }
]);

let p2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 30000);
}).then(() => {
  console.log('Timed out');
  return { result: true };
});

Promise.race([p1, p2]).then(v => { console.log(`And done with result ${v.result}`)})
  .catch(ex => { console.log(`Error: ${ex.message}`)});

Most helpful comment

Also, realize we were doing this here https://github.com/yeoman/insight/pull/51/files

var prompt = inquirer.prompt(...);
prompt.ui.close(); // will cancel the current prompt

All 5 comments

You could maybe trigger a SIGINT event on the readline?

Otherwise, a clean way could be to implement a custom prompt "confirm-with-timeout" that'd handle an answer timeout.

@SBoudrias Any pointers, documentation or examples I can look at to figure out how to write a custom prompt?

@christav I figure out that the original prompts are reference for writing your own prompt.
https://github.com/SBoudrias/Inquirer.js/tree/master/lib/prompts

You can use the custom prompt in your code just by registering the prompt

var inquirer = require('inquirer');
var timeoutPrompt = require('./prompts/my-shiny-new-timeout-prompt')

inquirer.registerPrompt('timeout',  timeoutPrompt );

var pmt = inquirer.prompt([{
    type: 'timeout',
    name: 'url',
    message: ' some random message',
    choices: choices,
    input: stdin,
}]).then(function (answers) {
    console.log (answers.name + " was selected")
});

Thanks for helping out @souravray :)

Also, realize we were doing this here https://github.com/yeoman/insight/pull/51/files

var prompt = inquirer.prompt(...);
prompt.ui.close(); // will cancel the current prompt
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Mrooze-zeng picture Mrooze-zeng  路  5Comments

XhmikosR picture XhmikosR  路  7Comments

apierzch picture apierzch  路  4Comments

fuechter picture fuechter  路  3Comments

sindresorhus picture sindresorhus  路  4Comments