I would like to have a Meteor method return true after a NodeJS script with createWriteStream has finished. However, currently it returns as soon as the createWriteStream starts. How can I get it to wait?
Here’s the code I have currently:
const fs = require( 'fs' );
const path = require( 'path' );
Meteor.methods({
importCSVServer( doc ) {
const urlObj = doc.importURL;
try {
let thisKey = urlObj.key.slice(1),
getS3params = {
Bucket: '<bucket_name>',
Key: thisKey
},
// Build a path string to the local CSV
csvFile = importDir + urlObj.name,
// Create a write stream for data to land when coming from S3
writeFile = fs.createWriteStream( csvFile ),
// Stream data from the CSV on S3 and pipe it to a new CSV on the server
getFile = S3.aws.getObject( getS3params ).createReadStream().pipe( writeFile );
// Watch for events on the write stream. When finished writing from S3, start processing
writeFile.
on( 'error', ( error ) => {
console.warn( 'writeFile error:' );
console.warn( error );
}).
on( 'finish', Meteor.bindEnvironment( ( error, response ) => {
Baby.parseFiles( csvFile, {
header: true,
step: ( results, parser ) => {
<process csv row here>
}, // End step function
complete: ( results, file ) => {
console.log( 'import finished' + ' at ' + moment().format() );
let deleteFile = fs.unlinkSync( csvFile );
return 'completed';
}
}); // end Baby.parseFiles
})); // end on.Finish
} catch ( error ) {
console.warn('import error' );
console.warn( error );
throw new Meteor.Error( 500, 'Import failed.' );
}
}
});
I have tried moving the writeStream
workflow to a separate function and have also looked at Meteor.wrapAsync
and Futures, but writeStream
always seems to destroy the order.
Appreciate any suggestions you may have.