Search code examples
javascriptnode.jsstreamnode.js-stream

Append text to a node.js stream on the go


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?


Solution

  • 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