0

am trying to upload multiple images to an external server so am looping in my FilesArray and on each element i trigger a httpRequest to upload the image to the server and i created a progress-bar to inform the user about the upload progress but the problem is that my loop doesn't wait for each element to end its subscription before moving to the next index it triggers the httpRequest all in parallel way which is normal , is there a way to wait for each element subscription to finish before moving to the next index element?

my upload function :

        let total = 0;
for (let index = 0; index < this.galleryPhotoFiles.length; index++) {

  this.galleryPhotosFormData.append("file", this.galleryPhotoFiles[index]);
  this.galleryPhotosFormData.append("upload_preset", [PRESET_NAME]);
  const req = new HttpRequest('POST', 'https://api.cloudinary.com/v1_1/[CLOUD_NAME]/image/upload', 
   this.galleryPhotosFormData,
    {
      headers: new HttpHeaders(),
      reportProgress: true,
    });


  this.http.request(req).subscribe(event => {

    if (event.type === HttpEventType.UploadProgress) {
      const percentDone = Math.round(100 * event.loaded / event.total);
      console.log(`File ${index} is ${percentDone}% uploaded.`);
    } else if (event instanceof HttpResponse) {
      console.log('File is completely uploaded!');
    }
  });

}
AOUADI Slim
  • 299
  • 1
  • 8
  • 27

1 Answers1

1

You could create your own events via EventEmitter. For example:

  1. Call upload function for the first image (on button click or however) - uploadImages()
  2. When image upload is done, emit an event - this.fileUploaded.emit(index)
  3. In the event handler function, upload next image - this.uploadImage(event + 1)

import { ..., EventEmitter } from '@angular/core';

...

    fileUploaded: EventEmitter<number>;
    
    ngOnInit(): void {
        this.fileUploaded = new EventEmitter<number>();
        this.fileUploaded.subscribe((event: number) => this.uploadImage(event + 1)); // register an event handler
    }
    
    uploadImages() { // on button click to upload images (assuming that's how you'd do it), you call this function
        this.uploadImage(0);
    }
    
    uploadImage(index: number) {
        if (index < 0 || index > this.galleryPhotoFiles.length) // important exit condition
          return;
    
        this.galleryPhotosFormData.append("file", this.galleryPhotoFiles[index]);
        this.galleryPhotosFormData.append("upload_preset", [PRESET_NAME]);
        const req = new HttpRequest('POST', 'https://api.cloudinary.com/v1_1/[CLOUD_NAME]/image/upload',
          this.galleryPhotosFormData,
          {
            headers: new HttpHeaders(),
            reportProgress: true,
          });
    
    
        this.http.request(req).subscribe(event => {
    
          if (event.type === HttpEventType.UploadProgress) {
            const percentDone = Math.round(100 * event.loaded / event.total);
            console.log(`File ${index} is ${percentDone}% uploaded.`);
          } else if (event instanceof HttpResponse) {
            console.log('File is completely uploaded!');
            this.fileUploaded.emit(index); // notify that the file with index 'index' has been uploaded completely 
          }
        });
    }

PajLe
  • 791
  • 1
  • 7
  • 21