Tim Fairbrother
Tim Fairbrother

Reputation: 929

Why does node finish/close when streaming input via process.stdin?

I am trying to create a node app that you can pipe in JSON data and display it as a question to the user.

I learned how to bind to process.stdin here http://dailyjs.com/2012/03/08/unix-node-pipes/

Here is an example. The following is my UI for asking questions in the terminal.

var inquirer = require("inquirer");

function runInquirer(choices) {
  inquirer.prompt([
    {
      type: "checkbox",
      message: "Select toppings",
      name: "toppings",
      choices: choices
    }
  ], function( answers ) {
    console.log( JSON.stringify(answers, null, "  ") );
  });
}

If I invoke the handler directly, it works

 runInquirer([
   {name:'Cheese'},
   {name:'Tomato'}
 ]);

But when I try to pipe the data into it

  process.stdin.resume();  
  process.stdin.setEncoding('utf8');  
  process.stdin.on('data', function(data) {        
    runInquirer(JSON.parse(data));
  });

It displays the questions and then exits immediately. So it is not waiting for my user input.

Example invoking from the command line (note the pipe | )

➜  test git:(master) ✗ cat questions.json | node test.js
? Select toppings (Press <space> to select)
 The usual:
 ❯◯ Peperonni
 ◉ Cheese

I have also tried this test with another node user interface library called https://github.com/yaronn/blessed-contrib and got the same result.

Upvotes: 2

Views: 586

Answers (1)

loganfsmyth
loganfsmyth

Reputation: 161457

You appear to be misunderstanding a bit about how processes handle stdin. inquirer.prompt sets up a prompt by using stdin and stdout to accept user input and write output to the terminal. process.stdin.on('data', sets up a handler to read data as it arrives on stdin. When you run

cat questions.json | node test.js

You are instructing your terminal to stop using the terminal as stdin and to instead use the output of the command cat as stdin.

That means that both of your methods of input are in fact trying to use the same channel. With your current structure, the answer to the question would also have to be coming from your questions.json file. It is exiting immediately because the file has run out of content and cannot possibly have any answers for your inquirer.

What you probably want is for your test.js file to accept a JSON file as the first argument, and read that file instead of reading from process.stdin.

Upvotes: 4

Related Questions