Посылать файлы через angular Http последовательно (последовательно) один за другим в angular с использованием оператора rx js concatMap () - PullRequest
0 голосов
/ 11 июля 2020

Я пытаюсь последовательно загрузить файлы с помощью корзины prefetchedUrl в S3.

Функция generateUrl (), используемая для генерации уникального URL-адреса для каждого загружаемого файла. Для загрузки файлов требуется уникальный идентификатор (stati c) и имя файла

  generateUrl(uniqueId, file) {
    var ext = (file.name).split(/\.(?=[^\.]+$)/);
    console.log(ext);
    return this.http.get<any>(`${this.baseURL}/v1/secure/upload/signed/${uniqueId}?filename=${file.name}.${ext}`);
  }

fileUpload (). Требуется уникальный URL-адрес, сгенерированный функцией generateUrl (), и файл для загрузки.

  uploadFilesByLink(url, file) {
    return this.http.put(url,file, {
      headers: { "Content-Type": file.type },
      reportProgress: true,
      observe:'events'
    })
  }

Теперь я пытаюсь сделать -

this.filesArray.forEach((file,index)=>{
     this.uploadsService.generateUrl(this.uniqueId, file)
        .pipe(
          concatMap(res1 => this.uploadsService.uploadFilesByLink(res1.url, file))
        ).subscribe(res2 => console.log(this.filesArray.indexOf(file),res2));
     })

Но это загрузка файлы параллельно. Пожалуйста помоги. Я пробовал много решений в Google.

Ответы [ 2 ]

0 голосов
/ 15 июля 2020

Я пробовал этот способ, и он работает.

upload.service.ts

  generateUrl(uniqueId, file) {
    console.log(file);
    var ext = (file.name).split(/\.(?=[^\.]+$)/);
    console.log(ext);
    return this.http.get<any>(`${this.baseURL}/v1/secure/upload/signed/${uniqueId}?filename=${file.name}.${ext}`)
      .pipe(
        map(
          res => {
           return {
             "url": res.url,
             "file":file
            }
          }
        )
      )
  }

upload-home.component.ts

 this.subscription = from(this.filesArray).pipe(
      concatMap(file => this.uploadsService.generateUrl(this.uniqueId, file)),
      concatMap(response => this.uploadsService.uploadFilesByLink(response.url, response.file))
    ).subscribe((event: HttpEvent<any>) => {

      switch (event.type) {
        case HttpEventType.Sent:
          console.log(' sent');
          break;
        case HttpEventType.ResponseHeader:
          console.log(' response header has been received');
          break;
        case HttpEventType.UploadProgress:
          // this.eventLoaded = event.loaded;
          this.progressInfo[this.it] = Math.round((event.loaded / event.total) * 100);
          console.log(event.loaded / event.total * 100);
          break;
        case HttpEventType.Response:
          // this.eventLoaded1 += this.eventLoaded;
          this.it++;
          console.log('it', this.it);

          this.responseArray.push(this.it);

          console.log('Uploaded');
          console.log(this.responseArray);

          // console.log(this.responseArray.length, this.filesArray.length);

          if (this.responseArray.length === this.filesArray.length) {
            console.log(this.emailOptions);

            if (this.emailOptions) {
              const controls = this.formGroup.controls;
              const from_email = controls.email_from.value;
              const to_email = controls.email_to.value;
              const message = controls.message.value;
              this.uploadsService.uploadFilesByEmail({
                "from_email": from_email,
                "to_email": [to_email],
                "message": message
              }, this.uniqueId).then(res => {
                this.uploadsService.afterUpdatingEmail(this.uniqueId).then(res => {
                  console.log('Uploaded By Email');

                  console.log(res);
                  this.it = 0;
                  this.filesArray = [];
                  this.fileSize = 0;
                  this.responseArray = [];
                  this.requestArrayLink = [];
                  this.subscription.unsubscribe();
                  this.successScreen = true;
                })
              })
            }
            else {
              this.it = 0;
              this.filesArray = [];
              this.fileSize = 0;
              this.responseArray = [];
              this.requestArrayLink = [];
              this.subscription.unsubscribe();
              console.log('Uploaded by Link');
              this.successScreen = true;
            }
          }
          else {
            console.log(this.it, 'uploaded');
          }
      }

    })
} 
0 голосов
/ 11 июля 2020

Вы можете попробовать использовать функцию Rx JS from вместе с оператором concatMap. from испускает элементы в массиве один за другим, в отличие от функции Rx JS of, которая не сглаживает входные данные и выдает массив как одно уведомление.

Попробуйте следующее

from(this.filesArray).pipe(
  concatMap(file => {
    const url = this.uploadsService.generateUrl(this.uniqueId, file);
    return this.uploadsService.uploadFilesByLink(url, file);
  })
).subscribe(
  res => console.log(res),
  err => // always good practice to handle HTTP errors,
  () => console.log('complete')
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...