Bird
Raised Fist0
Node.jsframework~20 mins

Piping streams together in Node.js - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Stream Piping Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What is the output of this Node.js stream piping code?
Consider the following code that reads from a readable stream, transforms data, and writes to a writable stream. What will be the final output written?
Node.js
import { Readable, Writable, Transform } from 'stream';

const readable = Readable.from(['a', 'b', 'c']);

const transform = new Transform({
  transform(chunk, encoding, callback) {
    this.push(chunk.toString().toUpperCase());
    callback();
  }
});

let result = '';
const writable = new Writable({
  write(chunk, encoding, callback) {
    result += chunk.toString();
    callback();
  }
});

readable.pipe(transform).pipe(writable);

writable.on('finish', () => {
  console.log(result);
});
A"ABC"
B"abc"
C"a b c"
D"undefined"
Attempts:
2 left
💡 Hint
Think about how the Transform stream changes the data before it reaches the writable stream.
📝 Syntax
intermediate
2:00remaining
Which option correctly pipes streams to handle errors?
You want to pipe a readable stream to a writable stream and handle errors properly. Which code snippet correctly attaches error handlers to both streams?
Areadable.pipe(writable).on('error', err => console.error('Writable error:', err)); readable.on('error', err => console.error('Readable error:', err));
Breadable.pipe(writable).on('error', err => console.error('Readable error:', err)); writable.on('error', err => console.error('Writable error:', err));
Creadable.pipe(writable); readable.on('error', err => console.error('Readable error:', err)); writable.on('error', err => console.error('Writable error:', err));
Dreadable.pipe(writable).on('error', err => console.error('Stream error:', err));
Attempts:
2 left
💡 Hint
Remember that pipe returns the destination stream, and error events must be handled on both streams separately.
🔧 Debug
advanced
2:00remaining
Why does this piping code cause a memory leak?
Examine the code below. Why might this cause a memory leak or high memory usage?
Node.js
import { Readable, Writable } from 'stream';

const readable = new Readable({
  read() {
    this.push('data');
  }
});

const writable = new Writable({
  write(chunk, encoding, callback) {
    setTimeout(() => {
      callback();
    }, 1000);
  }
});

readable.pipe(writable);
AThe readable stream never signals end, so it keeps pushing data endlessly, causing memory to grow.
BThe readable stream pushes data synchronously, which is not allowed and causes memory issues.
CThe pipe method is missing an error handler, causing unhandled errors and memory leaks.
DThe writable stream's callback is delayed, causing backpressure to build up and memory to increase.
Attempts:
2 left
💡 Hint
Think about how the readable stream signals the end of data.
state_output
advanced
2:00remaining
What is the value of 'count' after this stream piping completes?
This code counts how many chunks pass through a transform stream. What is the final value of 'count' after piping completes?
Node.js
import { Readable, Writable, Transform } from 'stream';

const readable = Readable.from(['x', 'y', 'z']);

let count = 0;
const transform = new Transform({
  transform(chunk, encoding, callback) {
    count++;
    this.push(chunk);
    callback();
  }
});

const writable = new Writable({
  write(chunk, encoding, callback) {
    callback();
  }
});

readable.pipe(transform).pipe(writable);

writable.on('finish', () => {
  console.log(count);
});
Aundefined
B0
C1
D3
Attempts:
2 left
💡 Hint
Count increments once per chunk transformed.
🧠 Conceptual
expert
2:00remaining
Which option best describes the behavior of stream piping with backpressure?
In Node.js streams, what happens when the writable stream is slower than the readable stream during piping?
AThe readable stream continues pushing data regardless, causing the writable stream to buffer indefinitely.
BThe readable stream pauses automatically to wait for the writable stream to catch up, preventing memory overflow.
CThe writable stream speeds up to match the readable stream's pace, so no data is lost.
DThe pipe method throws an error if the writable stream is slower than the readable stream.
Attempts:
2 left
💡 Hint
Think about how Node.js manages flow control between streams.

Practice

(1/5)
1. What is the main purpose of piping streams together in Node.js?
easy
A. To pause and resume streams manually
B. To convert streams into arrays for easier processing
C. To connect a readable stream directly to a writable stream for automatic data flow
D. To create new streams from scratch

Solution

  1. Step 1: Understand what piping does

    Piping connects a readable stream to a writable stream so data flows automatically without manual intervention.
  2. Step 2: Compare options

    Only To connect a readable stream directly to a writable stream for automatic data flow describes this automatic connection and data flow. Other options describe unrelated stream operations.
  3. Final Answer:

    To connect a readable stream directly to a writable stream for automatic data flow -> Option C
  4. Quick Check:

    Piping = automatic stream connection [OK]
Hint: Piping means connecting streams for automatic data transfer [OK]
Common Mistakes:
  • Thinking piping converts streams to arrays
  • Confusing piping with manual pause/resume
  • Assuming piping creates new streams
2. Which of the following is the correct syntax to pipe a readable stream readStream into a writable stream writeStream?
easy
A. readStream.pipe(writeStream);
B. writeStream.pipe(readStream);
C. pipe(readStream, writeStream);
D. readStream.write(writeStream);

Solution

  1. Step 1: Recall pipe method usage

    The pipe() method is called on a readable stream and takes a writable stream as argument.
  2. Step 2: Check each option

    readStream.pipe(writeStream); matches the correct syntax. writeStream.pipe(readStream); reverses streams, C uses a non-existent function, D misuses write method.
  3. Final Answer:

    readStream.pipe(writeStream); -> Option A
  4. Quick Check:

    Readable.pipe(Writable) = correct syntax [OK]
Hint: Remember: readableStream.pipe(writableStream) [OK]
Common Mistakes:
  • Reversing the order of streams in pipe
  • Using pipe as a standalone function
  • Calling write instead of pipe
3. Consider this code snippet:
const fs = require('fs');
const readStream = fs.createReadStream('input.txt');
const writeStream = fs.createWriteStream('output.txt');
readStream.pipe(writeStream);
writeStream.on('finish', () => console.log('Done'));

What will be printed when the piping finishes?
medium
A. No output
B. Error
C. undefined
D. Done

Solution

  1. Step 1: Understand the pipe and event

    The readable stream pipes data to the writable stream. When writing finishes, the 'finish' event triggers.
  2. Step 2: Check the event handler

    The code listens for 'finish' on writeStream and logs 'Done' when triggered.
  3. Final Answer:

    Done -> Option D
  4. Quick Check:

    'finish' event logs 'Done' [OK]
Hint: Listen to 'finish' event on writable stream for completion [OK]
Common Mistakes:
  • Expecting 'end' event on writable stream
  • Not handling asynchronous event
  • Confusing 'finish' with 'close'
4. What is wrong with this code snippet?
const fs = require('fs');
const readStream = fs.createReadStream('file.txt');
const writeStream = fs.createWriteStream('copy.txt');
writeStream.pipe(readStream);
medium
A. The file paths are incorrect
B. The pipe method is called on the writable stream instead of the readable stream
C. Missing error handling on streams
D. Streams cannot be piped in Node.js

Solution

  1. Step 1: Identify pipe usage

    The pipe method must be called on a readable stream, passing a writable stream as argument.
  2. Step 2: Analyze the code

    The code calls pipe on writeStream (writable), which is incorrect and will cause an error.
  3. Final Answer:

    The pipe method is called on the writable stream instead of the readable stream -> Option B
  4. Quick Check:

    Readable.pipe(Writable) only [OK]
Hint: Pipe is always called on readable stream [OK]
Common Mistakes:
  • Calling pipe on writable stream
  • Ignoring error handling (not main error here)
  • Assuming streams can't be piped
5. You want to read data from input.txt, compress it using zlib's gzip, and write the compressed data to output.gz. Which code snippet correctly pipes these streams together?
hard
A. const fs = require('fs'); const zlib = require('zlib'); const readStream = fs.createReadStream('input.txt'); const gzip = zlib.createGzip(); const writeStream = fs.createWriteStream('output.gz'); readStream.pipe(gzip).pipe(writeStream);
B. const fs = require('fs'); const zlib = require('zlib'); const readStream = fs.createReadStream('input.txt'); const gzip = zlib.createGzip(); const writeStream = fs.createWriteStream('output.gz'); gzip.pipe(readStream).pipe(writeStream);
C. const fs = require('fs'); const zlib = require('zlib'); const readStream = fs.createReadStream('input.txt'); const gzip = zlib.createGzip(); const writeStream = fs.createWriteStream('output.gz'); writeStream.pipe(gzip).pipe(readStream);
D. const fs = require('fs'); const zlib = require('zlib'); const readStream = fs.createReadStream('input.txt'); const gzip = zlib.createGzip(); const writeStream = fs.createWriteStream('output.gz'); readStream.pipe(writeStream).pipe(gzip);

Solution

  1. Step 1: Understand the stream flow

    Data flows from readable (input.txt) to transform (gzip) to writable (output.gz).
  2. Step 2: Check pipe chaining

    const fs = require('fs'); const zlib = require('zlib'); const readStream = fs.createReadStream('input.txt'); const gzip = zlib.createGzip(); const writeStream = fs.createWriteStream('output.gz'); readStream.pipe(gzip).pipe(writeStream); correctly pipes readStream into gzip, then gzip into writeStream. Other options reverse or misuse pipe order.
  3. Final Answer:

    readStream.pipe(gzip).pipe(writeStream); -> Option A
  4. Quick Check:

    Readable -> Transform -> Writable pipe chain [OK]
Hint: Chain pipes: readable.pipe(transform).pipe(writable) [OK]
Common Mistakes:
  • Reversing pipe order
  • Calling pipe on writable stream
  • Not chaining transform stream correctly