Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Node.js Cookbook

You're reading from   Node.js Cookbook Practical recipes for building server-side web applications with Node.js 22

Arrow left icon
Product type Paperback
Published in Nov 2024
Publisher Packt
ISBN-13 9781804619810
Length 456 pages
Edition 5th Edition
Languages
Tools
Arrow right icon
Authors (2):
Arrow left icon
Bethany Griggs Bethany Griggs
Author Profile Icon Bethany Griggs
Bethany Griggs
Manuel Spigolon Manuel Spigolon
Author Profile Icon Manuel Spigolon
Manuel Spigolon
Arrow right icon
View More author details
Toc

Table of Contents (15) Chapters Close

Preface 1. Chapter 1: Introducing Node.js 22 2. Chapter 2: Interacting with the File System FREE CHAPTER 3. Chapter 3: Working with Streams 4. Chapter 4: Using Web Protocols 5. Chapter 5: Developing Node.js Modules 6. Chapter 6: Working with Fastify – The Web Framework 7. Chapter 7: Persisting to Databases 8. Chapter 8: Testing with Node.js 9. Chapter 9: Dealing with Security 10. Chapter 10: Optimizing Performance 11. Chapter 11: Deploying Node.js Microservices 12. Chapter 12: Debugging Node.js 13. Index 14. Other Books You May Enjoy

Interacting with the file system

Standard in (stdin) refers to an input stream that a program can use to read input from a command shell or Terminal. Similarly, standard out (stdout) refers to the stream that is used to write the output. Standard error (stderr) is a separate stream to stdout that is typically reserved for outputting errors and diagnostic data.

In this recipe, we’re going to learn how to handle input with stdin, write output to stdout, and log errors to stderr.

Getting ready

For this recipe, let’s first create a single file named greeting.js. The program will ask for user input via stdin, return a greeting via stdout, and log an error to stderr when invalid input is provided. Let’s create a directory to work in, too:

$ mkdir interfacing-with-io
$ cd interfacing-with-io
$ touch greeting.js

Now that we’ve set up our directory and file, we’re ready to move on to the recipe steps.

How to do it…

In this recipe, we’re going to create a program that can read from stdin and write to stdout and stderr:

  1. First, we need to tell the program to listen for user input. This can be done by adding the following lines to greeting.js:
    console.log('What is your name?');
    process.stdin.on('data', (data) => {
      // processing on each data event
    });
  2. We can run the file using the following command. Observe that the application does not exit because it is continuing to listen for process.stdin data events:
    $ node greeting.js
  3. Exit the program using Ctrl + C.
  4. We can now tell the program what it should do each time it detects a data event. Add the following lines below the // processing on each data event comment:
      const name = data.toString().trim().toUpperCase();
      process.stdout.write(`Hello ${name}!`);
  5. You can now type input to your program. When you press Enter, it will return a greeting and your name in uppercase:
    $ node greeting.js
    What is your name?
    Beth
    Hello BETH!
  6. We can now add a check for whether the input string is empty and log to stderr if it is. Change your file to the following:
    console.log('What is your name?');
    process.stdin.on('data', (data) => {
      // processing on each data event
      const name = data.toString().trim().toUpperCase();
      if (name !== '') {
        process.stdout.write(`Hello ${name}!`);
      } else {
        process.stderr.write('Input was empty.\n');
      }
    });
  7. Run the program again and hit Enter with no input:
    $ node greeting.js
    What is your name?
    Input was empty.

We’ve now created a program that can read from stdin and write to stdout and stderr.

How it works…

The process.stdin, process.stdout, and process.stderr properties are all properties on the process object. A global process object provides information and control of the Node.js process. For each of the I/O channels (standard in, standard out, standard error), they emit data events for every chunk of data received. In this recipe, we were running the program in interactive mode where each data chunk was determined by the newline character when you hit Enter in your shell.

The process.stdin.on('data', (data) => {...}); instance is what listens for these data events. Each data event returns a Buffer object. The Buffer object (typically named data) returns a binary representation of the input.

The const name = data.toString() instance is what turns the Buffer object into a string. The trim() function removes all whitespace characters – including spaces, tabs, and newline characters – from the beginning and end of a string. The whitespace characters include spaces, tabs, and newline characters.

We write to stdout and stderr using the respective properties on the process object (process.stdout.write, process.stderr.write).

During the recipe, we also used Ctrl + C to exit the program in the shell. Ctrl + C sends SIGINT, or signal interrupt, to the Node.js process. For more information about signal events, refer to the Node.js Process API documentation: https://nodejs.org/api/process.html#process_signal_events.

Important note

Console APIs: Under the hood, console.log and console.err are using process.stdout and process.stderr. Console methods are higher-level APIs and include automatic formatting. It’s typical to use console methods for convenience and lower-level process methods when you require more control over the stream.

There’s more…

As of Node.js 17.0.0, Node.js provides an Experimental Readline Promises API, which is used for reading a file line by line. The Promises API variant of this allows you to use async/await instead of callbacks, providing a more modern and cleaner approach to handling asynchronous operations.

Here is an example of how the Promises API variant can be used to create a similar program to the greeting.js file created in the main recipe:

const readline = require('node:readline/promises');
async function greet () {
  const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
      });
  const name = await rl.question('What is your name?\n');
  console.log(`Hello ${name}!`);
  rl.close();
}
greet();

This Node.js script utilizes the node:readline/promises module, which provides the Promise variant of the Readline API. It defines an asynchronous function, greet(), which prompts the user for their name in the console and then greets them with a personalized message – similar to the main recipe program. Using the Readline Promises API allows us to use the async/await syntax for cleaner asynchronous code flow. We’ll cover more about the async/await syntax in later recipes and chapters.

See also

  • The Decoupling I/O recipe in Chapter 3
You have been reading a chapter from
Node.js Cookbook - Fifth Edition
Published in: Nov 2024
Publisher: Packt
ISBN-13: 9781804619810
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image