3

I'm trying to get my Node JS code to work step by step instead of asynchronously using Promise then.

I first delete all the spreadsheets, then generate them, then zip them, then encrypt the zip, then send the zip via email, then delete the spreadsheets.

//Schedules the job at a specific time var start = schedule.scheduleJob({ hour: 19, minute: 26, dayOfWeek: 3 }, function() { sendIt(); }); //Starts the Promise Chain function sendIt() { return deleteSpreadsheets().then(generateSpeadsheets).then(zipSpreadsheets).then(encrypt).then(sendEmail).then(deleteSpreadsheets); } //Deletes the current Spreadsheets in the folder function deleteSpreadsheets() { var promise = new Promise(function(resolve, reject) { console.log('Deleting Spreadsheets'); var locationSpread = ['Location.xlsx']; locationSpread.forEach(function(filename) { if (fs.existsSync("./Spreadsheets/" + filename)) { fs.unlink("./Spreadsheets/" + filename, (err) => { if (err) { console.log('Spreadsheet ' + filename + ' not found'); } else { console.log('Spreadsheet ' + filename + ' successfully deleted'); } }); } }); resolve(); }); return promise; } //Generates the new Spreadsheets function generateSpeadsheets() { var promise = new Promise(function(resolve, reject) { console.log('Generating Spreadsheets'); var locationSpread = ['Location.xlsx']; locationSpread.forEach(function(filename) { var query = connection.query('SELECT * from ' + filename.slice(0, -5), function(err, rows) { var workbook = excelbuilder.createWorkbook('./Spreadsheets/', filename); if (workbook == null) { console.log('workbook null') }; var sheet = workbook.createSheet(filename.slice(0, -5), 3, rows.length + 1); if (sheet == null) { console.log('sheet null') }; sheet.set(1, 1, 'First Name'); sheet.set(2, 1, 'Last Name'); sheet.set(3, 1, 'Company'); for (var j = 2, z = 0; z < rows.length; j++, z++) { sheet.set(1, j, rows[z].firstName); sheet.set(2, j, rows[z].lastName); sheet.set(3, j, rows[z].company); } workbook.save(function(err) { console.log('workbook saved ' + (err ? 'failed' : 'ok')); }); }); }); resolve(); }); return promise; } //Generates a Zip file with all the Spreadsheets function zipSpreadsheets() { var promise = new Promise(function(resolve, reject) { console.log('Zipping Spreadsheets'); var zipFolder = require('zip-folder'); zipFolder('./Spreadsheets/', './Spreadsheets.zip', function(err) { if (err) { console.log('Failed to zip folders', err); reject(); } else { console.log('Successfully zipped folder'); } }); resolve(); }); return promise; } //Encrypts the Spreadsheet function encrypt() { var promise = new Promise(function(resolve, reject) { console.log('Encrypting'); spawn = require('child_process').spawn; zip = spawn('zip', ['-P', 'something', 'Encrypted.zip', './Spreadsheets.zip']); zip.on('exit', function(code) { console.log('Finished encrypting'); resolve(); }); }); return promise; } //Sends the Encryped Zip as an attached in an email function sendEmail() { var promise = new Promise(function(resolve, reject) { console.log("MAIL SCHEDULE RUNNING"); var transporter = nodemailer.createTransport({ service: 'Gmail', auth: { user: 'email', // Your email id pass: 'password' } }); var content = 'something'; var mailOptions = { from: 'email', // sender address to: 'email', // list of receivers subject: 'Title', // Subject line text: content, attachments: [{ // file on disk as an attachment filename: 'Encrypted.zip', path: './Encrypted.zip' // stream this file }] }; transporter.sendMail(mailOptions, function(error, info) { if (error) { console.log(error); reject(); } else { console.log('Message sent: ' + info.response); resolve(); }; }); }); return promise; }

This doesn't seem to be working as planned as seen in the logs:

Deleting Spreadsheets Generating Spreadsheets Zipping Spreadsheets Encrypting **Spreadsheet Location.xlsx successfully deleted** **Finished encrypting** MAIL SCHEDULE RUNNING **Successfully zipped folder** **workbook saved ok** Message sent: ----------------------------------------------- Deleting Spreadsheets Spreadsheet Location.xlsx successfully deleted 

Here's what it should be:

Deleting Spreadsheets **Spreadsheet Location.xlsx successfully deleted** Generating Spreadsheets **workbook saved ok** Zipping Spreadsheets **Successfully zipped folder** Encrypting **Finished encrypting** MAIL SCHEDULE RUNNING Message sent: ----------------------------------------------- Deleting Spreadsheets Spreadsheet Location.xlsx successfully deleted 
2
  • You call resolve() immediately without waiting for the asynchronous actions. That's not how promises work - you have to call it from the asynchronous callback. Commented Aug 16, 2017 at 23:54
  • You should promisify every asynchronous function (like unlink, query, save etc) on its own, so that you can compose them and also create an array of promises in those loops that you can await concurrently. Commented Aug 16, 2017 at 23:58

1 Answer 1

2

You are returning the promise, then resolving in the wrong way. Also you are not waiting for all the deletions to happen. Check this out.

function deleteSingle(filename) { return new Promise((resolve, reject) => { if (fs.existsSync("./Spreadsheets/" + filename)) { fs.unlink("./Spreadsheets/" + filename, (err) => { //handle errors or whatever return resolve(); }); } else { //handle if file doesnt exist return resolve(); } }) } //Deletes the current Spreadsheets in the folder function deleteSpreadsheets() { //we are maping each value inside locationSpread and passing it to the deleteSingle function which returns a promise return Promise.all(locationSpread.map(deleteSingle)) } 

So, I splitted your code. deleteSingle function returns a promise which resolves once the file is deleted (it also resolves if the file is not deleted or doesnt exist, you modify it to do whatever you want).

Then, the deleteSpreadsheets function returns a single promise, which will be resolved once the array of promises inside resolves. So you can call deleteSpreadsheets().then.... etc

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.