'how to get callback of collection.each{fn} discord.js

I want to make a discord bot that should get all image attachements and merge them into 1 pdf.

I have divided my problem into 2 steps, downloading and converting to pdf.

I've been successful at downloading and converting 1 image, using callbacks on the download function.

But now I want to download multiples images that will then be merged in to 1 pdf. I can't make a callback for every image I download because I want to wait until all the images are downloaded to merge them.

(I name images according to their number to make it easier for me to identify them at the merging process).

Here is my code:

client.on('messageCreate', msg => {
  if (msg.author.bot) return;
  
  file_number = 0

  var attachments = msg.attachments
  attachments_size = attachments.size

  attachments.each(attachment => {
    var url = attachment ? attachment.url : null;
    file_number += 1
    file_name = file_number + '.jpeg'
    download(url, file_name, function(){
    })


  })

  
  convert_merge()
  

});


var download = function(uri, filename, callback){
  request.head(uri, function(err, res, body){
    request(uri).pipe(fs.createWriteStream('./files/'+ filename)).on('close', callback);
  });
};



var convert_merge = function(callback){

  var doc = new PDFDocument
  var doc_width = doc.page.height
  var doc_height = doc.page.width
 
  var writeStream = fs.createWriteStream('./files/merged.pdf')
  doc.pipe(writeStream)
  doc.rotate(90, {origin: [doc_width/2, doc_height/2]});

  
  doc.image('./files/'+ `1.jpeg`, {
   fit: [doc_width+25, doc_height+35],
   align: 'center',
   valign: 'center'
  });

  

  for (var i = 1; i <= file_number ; ++i) {
    
    doc.addPage()
     .image('./files/'+ i + `.jpeg`, {
     fit: [doc_width+25, doc_height+35],
     align: 'center',
     valign: 'center'
    });
    
  }
  
  doc.end()

};

This is the error i have:

node:internal/fs/utils:344
    throw err;
    ^

Error: ENOENT: no such file or directory, open './files/1.jpeg'

This means that 1.jpeg doesn't exist yet, this can only mean that convert_merge is firing before attachments.each{} finishes

This makes me question 2 things:

  1. Why is JavaScript firing the convert function before the attachement.each call ?
  2. Is there a callback for the attachement.each call ?

Finally, how should I go over this problem? I have thought of checking if last file of the attachment exists before starting the conversion but I was unsuccessful and it seemed not to be the right way to go.

Looking for any advice

Feel free to ask for anything

Thanks in advance for your help :)



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source