Interacting with the Console in Node.js
Node.js provides the low-level interaction with the operating system particularly through input and output (I/O) operations. It includes core APIs that allows developer to handle with I/O streams, interact with the file system and manage the networking tasks efficiently. In this article, we will focus on interacting the console by exploring how to read and write input from the user and handle errors.
Interacting with Console
Before delving into the file system, we’re going to learn how to handle input with stdin, write output to stdout and log errors to stderr. Standard in (stdin) refers to an input stream that a program can use to read input from a Command Shell or Terminal. Also, Standard out (stdout) refers to the stream that is used to write the output. Lastly, Standard error (stderr) is a separate stream to log output data and diagnostic data.
Let’s create a file called greeting.js
for user input via stdin, return via stdout and log an error to stderr
when an input is invalid. First, we need to tell the program to listen the user input. This can be done by adding the
following codes to the greeting.js.
console.log("What's your name?");
process.stdin.on("data", (data) => {
const name = data.toString().trim();
process.stdout.write(`Hello ${name}`);
});
We can run the file using the following command. Now, the program listens for process.stdin
data events.
node greeting.js
After that, we can type input to the program. When pressing Enter, it will return the input data.
node greeting.js
What's your name?
Alex
Hello Alex
Moreover, we can check if the input string is empty, we’ll log to stderr
. Let’s change the file to the following
code.
console.log("What's your name?");
process.stdin.on("data", (data) => {
const name = data.toString().trim();
if (name === "") {
process.stderr.write("Input is empty!\n");
} else {
process.stdout.write(`Hello ${data}`);
}
});
Restart the program again and press Enter with no input.
node greeting.js
What's your name?
Input was empty!
We’ve created a program that can read data from stdin, write data to stdout and log error to stderr.
How does it work?
The process.stdin
, process.stdout
, process.stderr
are properties on the process object. A
process object is a global object that provides information and control of the Node.js process. For each I/O
(standard in, standard out, standard error), they emit data events for every chunk of data they received.
The process.stdin.on
instance listens for these data events. Each data event return a Buffer object.
The Buffer object returns a binary representation of the input. The const name = data.toString().trim();
instance turns the Buffer object into a string. The trim()
function removes all whitespace characters including
spaces, tabs and newline character.
Also, stdout
and stderr
uses the perspective properties on the process object. During the program, we also used
Ctrl + C to exit the program in the terminal. Ctrl + C sends the signal called SIGINT
which is known as signal
interrupt to the Node.js process. For further information about signal events, we can reach out to the
Node.js Process API documentation.
Alternative approach with readline
At the version 17.0.0, Node.js provides an Readline Promises API which is used for reading a file line by line. The
Promises API allow us to use with async / await
instead of callbacks which provides more modern and cleaner approach
to handle asynchronous operations.
Here is the another example of a similar program to the greeting.js
.
const readline = require("readline/promises");
async function greet() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const name = await rl.question("What's your name?\n");
console.log(`Hello ${name}`);
rl.close();
}
greet();
This program utilizes the readline/promises
module which provides the Promise variant of the Readline API. It
defines the asynchronous function called greet()
to prompt the user input in the console which is similar to the
previous program. This appraoch uses the Readline Promises API with async / await
syntax for cleaner asynchronous
code.
We’ve explored how the Node.js handles the console interactions using process.stdin
, process.stdout
and process.stderr
for user input, processes data and logs errors. Additionally, we’ve used readline/promises
module which provides a modern and cleaner way to handle user input with asynchronous operations. Understanding
these fundamental I/O mechanisms is essential for building more interactive and robust Node.js applications.