Alex Ironside
Alex Ironside

Reputation: 5039

Waiting until readStream has ended and returning the data

This is my code:

downloadFile(file_id) {
    var mongoose = require('mongoose');
    var Grid = require('gridfs-stream');
    var fs = require('fs');

    mongoose.connect(config.db, {useNewUrlParser: true},).catch(e => console.log(e));
    var conn = mongoose.connection;
    Grid.mongo = mongoose.mongo;
    var gfs = Grid(conn.db);
    console.log('downloadfile', file_id);
    var read_stream = gfs.createReadStream({_id: file_id});
    let file = [];
    read_stream.on('data', function (chunk) {
        file.push(chunk);
    });
    read_stream.on('error', e => {
        console.log(e);
    });
    return read_stream.on('end', function () {
        console.log('file', file); // This logs the file buffer
        return file;
    });
}

And this is how I'm trying to use it:

Account.findById(req.params._id)
    .then(async account => {
        const file = await functions.downloadFile(account.employer.logo);
        console.log(file); // This logs the readStream data
        res.render('users/employer/booth', {
            title: 'Employer Booth',
            user: req.user,
            postings: postings,
            employer: account.employer,
            event: event,
            logo: logo,
        });
    });

And I guess it would be easy to get the downloaded file in a callback, but how can I pass this file back, and make the code execution wait?

This is how the logged file looks like file [ <Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 fa 00 00 00 fa 08 06 00 00 00 88 ec 5a 3d 00 00 00 01 73 52 47 42 00 ae ce 1c e9 00 00 20 00 ... > ]

So to summarize. Right now, the code doesn't wait. It logs the readStream itself, and then logs the file data. How can I make it wait for the stream to end and return the file to my router?

Upvotes: 2

Views: 5325

Answers (1)

front_end_dev
front_end_dev

Reputation: 2056

Wrap your downloadFile function into promise object and resolve only after completely read of file and in case of error reject the promise.

Update Code

function downloadFile(file_id) {
    return new Promise((resolve, reject) => {
        var mongoose = require('mongoose');
        var Grid = require('gridfs-stream');
        var fs = require('fs');

        mongoose.connect(config.db, { useNewUrlParser: true },).catch(e => console.log(e));
        var conn = mongoose.connection;
        Grid.mongo = mongoose.mongo;
        var gfs = Grid(conn.db);
        console.log('downloadfile', file_id);
        var read_stream = gfs.createReadStream({ _id: file_id });
        let file = [];
        read_stream.on('data', function (chunk) {
            file.push(chunk);
        });
        read_stream.on('error', e => {
            reject(e);
        });
        return read_stream.on('end', function () {
            console.log('file', file); // This logs the file buffer
            resolve(file);
        });
    });
}

Upvotes: 7

Related Questions