0

The code here intend to save the images uploaded in multipart/form-data (files have been successfully parsed in multiparty module) to Amazon S3, then get all the image bucket URLs and save it to imageUrl array field in the mongodb. However, the imageUrl is always empty. I found out inside the loopwithcb function the imageUrl has correct URLs. In the callback function afterSave, the imageUrl is empty. I think it is asynchronous problem, but still cannot figure it out. Any thought would be helpful.

//save images to S3
var i=-1;
var imageUrl =[];
function loopwithcb(afterSave){
  Object.keys(files.files).forEach(function(){
  i=i+1;
  var myFile = files.files[i];
  var fileName = Date.now()+myFile.originalFilename;
  s3Client.upload({
      Bucket: bucket,
      Key: fileName,
      ACL: 'public-read',
      Body: fs.createReadStream(myFile.path)
      //ContentLength: part.byteCount
  }, function (err, data) {
      if (err) {
          //handle error
      } else {
          //handle upload complete
          var s3url = "https://s3.amazonaws.com/" + bucket + '/' + fileName;
          imageUrl.push(s3url);
          console.log('imageurl:'+ imageUrl);
          //delete the temp file
          fs.unlink(myFile.path);
          console.log('url:' + imageUrl);                              
      }
  });
  });
  afterSave();
}
function afterSave(){
  console.log('i:'+ i);
  console.log('outside print imageurl:'+ imageUrl);
    Listing.create({ 
      title : fields.ltitle, 
      type : 'newlist',
        description : fields.lbody,
        image : imageUrl
        }, function (err, small) {
        if (err) return handleError(err);
        // saved!
        console.log(small);
        console.log('listingId:' + ObjectId(small._id).valueOf());
        //res.json(small);
  });
}
loopwithcb(afterSave);  //call back
J.C.
  • 61
  • 1
  • 3
  • 12

1 Answers1

0

Changed some part of code, now it can print out the correct imageUrl. However, the new code will NOT upload files to AWS S3. Found this solution (async for loop in node.js) is exactly what I want.

 function loopwithcb(afterSave){
  Object.keys(files.files).forEach(function(){
  i=i+1;
  var myFile = files.files[i];
  var fileName = Date.now()+myFile.originalFilename;
  var saved = s3Client.upload({
      Bucket: bucket,
      Key: fileName,
      ACL: 'public-read',
      Body: fs.createReadStream(myFile.path)
      //ContentLength: part.byteCount
  });     
  if (saved.err) {
      //handle error
  } else {
      //handle upload complete
      var s3url = "https://s3.amazonaws.com/" + bucket + '/' + fileName;
      imageUrl.push(s3url);
      console.log('imageurl:'+ imageUrl);
      //delete the temp file
      fs.unlink(myFile.path);
      console.log('url:' + imageUrl);                              
  }      
  });
  afterSave();
}
J.C.
  • 61
  • 1
  • 3
  • 12