convert mongoose stream to array convert mongoose stream to array mongoose mongoose

convert mongoose stream to array


The only problem I am facing here is that I don't know when it is the last JSON object in the stream.

But you do know which one is first. Knowing that, instead of appending the comma, you can prepend it to every object except the first one. In order to do that, set up your transform function inside a closure:

function transformFn(){    var first = true;    return function(data) {        if (first) {            first = false;            return JSON.stringify(data);        }        return "," + JSON.stringify(data);    }}

Now you can just call that function and set it as your actual transform.

var transform = transformFn();res.write("[");var dbStream = db.node.find({'dataset': dataSetRef}).lean().stream({'transform': transform});dbStream.on("end", function(){    res.write("]");});dbStream.pipe(res);


@cbajorin and @rckd both gave correct answers.

However, repeating this code all the time seems like a pain.

Hence my solution uses an extra Transform stream to achieve the same thing.

    import { Transform } from 'stream'class ArrayTransform extends Transform {    constructor(options) {        super(options)        this._index = 0    }    _transform(data, encoding, done) {        if (!(this._index++)) {            // first element, add opening bracket            this.push('[')        } else {            // following element, prepend comma            this.push(',')        }        this.push(data)        done()    }    _flush(done) {        if (!(this._index++)) {            // empty            this.push('[]')        } else {            // append closing bracket            this.push(']')        }        done()    }}

Which in turn can be used as:

const toArray = new ArrayTransform();Model.find(query).lean().stream({transform: JSON.stringify })    .pipe(toArray)    .pipe(res)

EDIT: added check for empty


I love @cdbajorin's solution, so i created a more readable version of it (ES6):

Products    .find({})    .lean()    .stream({        transform: () => {            let index = 0;            return (data) => {                return (!(index++) ? '[' : ',') + JSON.stringify(data);            };        }() // invoke    })    .on('end', () => {        res.write(']');    })    .pipe(res);