2

I am using fs.createReadStream() to read files, and then pipe them to the response.

I want to add a small Javascript function when I'm serving HTML files.

The only way I can think of is to read the file into a string, append the text to the string, and then stream the string to the response, but I think there could be a better/faster way to do this.

Is there a way for me to append the text to the file on the go?

Omar A
  • 435
  • 7
  • 14
  • 1
    You can use something like [`through`](https://www.npmjs.com/package/through) to do this. It takes a read and write function and lets you transform the stream without resorting to storing large arrays in memory. – Matthew Bakaitis Dec 11 '14 at 15:29
  • @MatthewBakaitis Thank you for this suggestion. After reading about through and looking through its issues on github, I saw its developer recommend through2 for a case similar to mine. So, thanks mainly to you, I'm now using through2 and the issue is resolved :) Should you turn this into an anwser for me to accept it? – Omar A Dec 14 '14 at 17:43
  • I think this works best as a comment. It's not a detailed code question which is what usually is best as a detailed answer. You might want to edit your question to add a bit at the end that says you found through2 via the comments for anybody who finds your question via search... – Matthew Bakaitis Dec 15 '14 at 15:20

1 Answers1

0

After @Matthew Bakaitis's suggestion to use through and after reading for a while about it and checking the issues on github, I found through's developer recommending through2 for a case similar to mine.

Better implementation using finish callback

let str_to_append="Whatever you want to append"

let through_opts = { "decodeStrings": false, "encoding": "utf8" }

let chunk_handler = function (chunk, enc, next) {
    next(null, chunk)
}

let finish_handler = function (done) {
    this.push(str_to_append)
    done()
}

let through_stream = through2.ctor(through_opts, chunk_handler, finish_handler)

Old Implementation

This is how I implemented the solution:

var through2 = require("through2");

var jsfn="<script>function JSfn(){ return "this is a js fn";}</script>";

var flag=0;

fileStream.pipe( 
    through2( {"decodeStrings" : false, "encoding": "utf8"},function(chunk, enc) {
        if(flag===0) {
            var tempChunk=chunk;
            chunk=jsfn;
            chunk+=tempChunk;
            flag=1;
        }
        this.push(chunk);
    })
).pipe(res);

The option decodeStrings must be set to false so that the chunk of data is a string and not a buffer. This is related to the transform function of the stream api, not to through2.

More info on transform

Omar A
  • 435
  • 7
  • 14