Search code examples
angularazurerxjsazure-storageazure-blob-storage

Loop through files to upload doesn't work


I'm trying to create a (multi)file upload in Angular. I want the user to select one or more files, call my backend to fetch shared access signatures for Azure Blob Storage, and then upload the files form the client to Azure Storage.

My problem is, that after file selection I want to loop through the selected files and invoke the upload process per file.

onFileChange(event: any): void {
  this.filesSelected = true;
  this.uploadProgress$ = from(event.target.files as FileList).pipe(
    map(file => this.uploadFile(file)),
    combineAll()
  );
}

I found the code above in an example here: https://medium.com/@stuarttottle/upload-to-azure-blob-storage-with-angular-7977e979496a and it seems like a good solution. I tweaked the code so I retrieve a SAS per file and left everything else as is. My problem is that the map doesn't file. It doesn't matter if I select one or multiple files. Debugging shows that the selected files do indeed arrive (the event.target.files is actually a FileList with the files selected), but the map operator simply doesn't fire. Reviewing the code I cannot find an issue. Maybe you guys can help ;)

[edit] Added uploadFile requestion in comments

uploadFile(file: File): Observable<IUploadProgress> {
  return this.picturesService.acquireSas(file.name).pipe(
    flatMap(sas => {
      const accessToken: ISasToken = {
        container: sas.containerName,
        filename: file.name,
        storageAccessToken: sas.valetKeySecret,
        storageUri: sas.storageUrl
      };
      return this.blobStorage
        .uploadToBlobStorage(accessToken, file)
        .pipe(map(progress => this.mapProgress(file, progress)));
    })
  );
}

[/edit]


Solution

  • Everything you did is just fine. You just need to subscribe the observable.

    Like this.uploadProgress$.subscribe();

    Working example here.

    You can learn about rxjs @ learnrxjs.io