Node Input/Output basics

note:
stdin = standard input
stdout = standard output

DOCS: https://nodejs.org/docs/v0.6.6/api/fs.html

Lets say you want to create a simple app with node that asks the user for some input and outputs some info or does something with the inputted data.

Node has a global object called process that has 2 properties called .stdin & .stdout, which are essentially streams. You can write things into the stdout and listen to the ‘data’ event in the stdin stream.

Lets create a simple example that asks the user for their name, the outputs the users name.

var stdin = process.stdin, stdout = process.stdout

console.log('please enter your name >');

stdin.resume();
stdin.setEncoding('utf8');

stdin.on('data', function(data) {
  stdout.write(`so your name is ${data}`);
});

heres what we did:

  1. Set vars for stdin/stdout (this isnt required)
  2. console.log() prompted the user to ask for their name
  3. .resume() is required to initialize STDIN
  4. set the encoded of the input recieved
  5. set an asyncronous event handler onto stdin using .on that fires everytime the user hits Enter basically.
  6. use stdout.write() to write to the console once enter is hit.

a problem with this is that it will keep running continuously if the user keeps hitting Enter. Lets create a question asking function that we can call, chaining together with callbacks that will ask the user for information, and reask the question if there is no input.

function ask(question, callback) {
  var stdin = process.stdin, stdout = process.stdout;

  stdin.resume();
  stdout.write(`${question}: `);

  stdin.once('data', function(data) {
    data = data.toString().trim();

    if (!data || data === '') {
      stdout.write('Please enter some data bro... \n');
      ask(question, callback);
    }
    else {
      callback(data);
    }
  })
}


ask('what is your name?', function(name) {
  ask('what color are your eyes?', function(eyes) {
    console.log(`your name is ${name}, and you have ${eyes} colored eyes`);
    process.exit();
  });
});

heres whats happening:

  1. we are creating a function with a callback so we can chain or next questions so it will keep asking.
  2. of course, .resume() to init .stdin.
  3. we use stdout.write() to ask the question, which is entered when we initialize our function.
  4. our event handler uses .once() instead of .on() this time, so the program will not continue to ask for an Enter.
  5. inside of our stdin.once() event handler we call .toString().trim() to format the users input.
  6. if there is no input, or if the input is equal to an empty string, we use recursion and re-ask t.e question
  7. if no formatting problems, we use our callback(data) to pass the data to a callback function.
  8. now if we call the ask() function we have created in the following format: ask(<question to be asked>, <func(data) to be called with data == inputted infomation>)