0

I know many topics has been about promises and callback. I tried many ways but still, I don't succeed to solve it.

What I want is to edit a file locally, save it then upload it to S3. then another function is called to read from the file and display as a list

Unfortunately I am having error because the file is ending call another function to display to read then it is writing and saving in S3 as you can see in my [terminal ][1] the file is properly edited and uploaded to s3

1- I tried as promises using then to excecute one after another

static async edit_product(req: any, res: any) {
    console.log('edit_product param request',req.body)
    try {
       ExcelFile.EditFile(prod.product_code,prod.product_name).then(rs=> res.status(200).json({'success'}) ) ).catch((err) => {
        console.error(err);
            })
            console.log('test')
        }

2- using await and then

static async edit_product(req: any, res: any) {
    console.log('edit_product param request',req.body)
    try {
        await ExcelFile.EditFile(prod.product_code,prod.product_name).then(rs=> rs)
        console.log('test')
        res.status(200).json({'success product edit':prod.product_code})
   }

3-to upload file to S3

static async UploadFileS3() {
            const file = config._path+config._foldername +config._filename
            var s3 = new aws.S3({ accessKeyId: config._ACCESS_KEY_ID,secretAccessKey: config._SECRET_ACCESS_KEY });
            var newversionId: string = ''
            const params = {
                    Bucket: config._BUCKET_NAME,
                    Key: config._filename // File name you want to save as in S3
               };
           return  s3.putObject(params, function(err, data) {
                    if (err) {console.log(err) }
                    newversionId = data.VersionId!
                    console.log("Successfully uploaded data ",newversionId);
              });
};

4-edit file

      const stream = new Stream.PassThrough();
      var dataFile =  wb.xlsx.readFile(file).then(rs=>{
      var sh = rs.getWorksheet(config._sheetname);
      for (let i = 2; i <= sh.rowCount; i++) { 
       let currRow =  sh.getRow(i); 
       if (currRow.getCell(1).text==product_code){
          currRow.getCell(2).value = product_name
          currRow.commit();
         break                           } }  
      console.log('edit ')
//save locally
      wb.xlsx.writeFile(file).then(rs=>{console.log('edit filed successfully')});
      const param = {Key: config._filename,
                     Bucket: config._BUCKET_NAME,
                     Body: stream,
                     ContentType: 'CONTENT_TYPE_EXCEL'
                     }
//save to s3 
     wb.xlsx.write(stream).then(() => {s3.upload(param, function (err,data) {    
              if (err) { console.log("Error", err);  }  
              console.log("Upload Success", data.ETag);
          ExcelFile.getAwsVersion().then(rs=>ExcelFile.saveFileBucketVersion(rs))
                                                                                                        })
                                })
                        })
                        return dataFile //return promise

How can I make it to respect the step, edit first then return res.status(200).json({'success'} [1]: https://i.stack.imgur.com/SsWhu.png

haly
  • 15
  • 5
  • Since `s3.putObject()` accepts a nodeback, it seems unlikely that it also returns Promise. If so then `UploadFileS3()` returns something that will not be awaited either by `await` or `.then()` syntax. – Roamer-1888 Feb 18 '21 at 07:09

1 Answers1

0

Your EditFile function seems to be not waiting for the end of the writeFile. The for loop starts the writeFile function but it is not awaited there. The possible solutions are

  1. Move the write function out of the for loop. It looks weird anyway that you are potentially saving the changes multiple time.

  2. If the write should be in the loop then use a promise compatible loop there (e.g. Bluebird.each)

Zoltan Magyar
  • 874
  • 1
  • 6
  • 19