Reputation: 3428
I'm trying to extend the node.js Transform stream twice, once to split stdin into new lines, and another to alternate lowercase and uppercase.
SplitLines
is working as intended, but AlternateUppercase
is not.
const { Transform } = require('stream')
class SplitLines extends Transform {
_transform(chunk, encoding, callback) {
const parsed = chunk.toString().trim()
const results = parsed.split('\n')
results.forEach((line) => {
this.push(`${line}\n`)
})
}
}
class AlternateUppercase extends Transform {
constructor(options) {
super(options)
this.isEven = false
}
_transform(chunk, encoding, callback) {
const line = chunk.toString()
const altered = this.isEven ? line.toUpperCase() : line
this.push(`${altered}\n`)
this.isEven = !this.isEven
}
}
process.stdin
.pipe(new SplitLines())
.pipe(new AlternateUppercase())
.pipe(process.stdout)
echo -e 'one\ntwo\nthree' | node index.js
one
one
TWO
three
Am I doing something wrong which is causing
Upvotes: 0
Views: 752
Reputation: 197
In the node documentation, you are required to call the callback
function in order to receive the next chunk. This is not so apparent in the SplitLines
function because you passed the whole string as a single chunk. However, when you do the push operation repeatedly SplitLines
, you are sending multiple chunks, so you need to call the callback
function.
const { Transform } = require('stream')
class SplitLines extends Transform {
_transform(chunk, encoding, callback) {
const parsed = chunk.toString().trim()
const results = parsed.split('\n')
results.forEach((line) => {
this.push(`${line}\n`)
})
}
}
class AlternateUppercase extends Transform {
constructor(options) {
super(options)
this.isEven = false
}
_transform(chunk, encoding, callback) {
const line = chunk.toString()
const altered = this.isEven ? line.toUpperCase() : line
this.push(`${altered}\n`)
callback() //must call callback to receive next chunk
this.isEven = !this.isEven
}
}
process.stdin
.pipe(new SplitLines())
.pipe(new AlternateUppercase())
.pipe(process.stdout)
The output would be:
one
TWO
three
The multiple new lines appeared because you \n
at both of the transformer. To fix this, you need to add \n
only once, ie at SplitLines or AlternateUppercase only.
Upvotes: 1