簡體   English   中英

Angular 2同步文件上傳

[英]Angular 2 Synchronous File Upload

我正在嘗試將文件上傳到web api,它使用angular 2應用程序將文件作為字節數組。

我無法將字節數組從角度2頁面傳遞給web api。 看起來File Reader讀取方法是異步的。 在執行下一行代碼之前,如何將其作為同步調用或等待加載文件內容?

以下是我的代碼

//attachment on browse - when the browse button is clicked
//It only assign the file to a local variable (attachment)
fileChange = (event) => {
    var files = event.target.files;
    if (files.length > 0) {
        this.attachment = files[0];
    }
}

//when the submit button is clicked
onSubmit = () => {


        //Read the content of the file and store it in local variable (fileData)
        let fr = new FileReader();
        let data = new Blob([this.attachment]);
        fr.readAsArrayBuffer(data);
        fr.onloadend  = () => {
            this.fileData = fr.result; //Note : This always "undefined"
        };


        //build the attachment object which will be sent to Web API
        let attachment: Attachment = {
            AttachmentId: '0',
            FileName: this.form.controls["attachmentName"].value,
            FileData: this.fileData
        }

        //build the purchase order object
        let order: UpdatePurchaseOrder = {
            SendEmail: true,
            PurchaseOrderNumber: this.form.controls["purchaseOrderNumber"].value,
            Attachment: attachment
        }

        //call the web api and pass the purchaseorder object
        this.updatePoService
            .updatePurchaseOrder(this.form.controls["purchaseOrderRequestId"].value, order)
            .subscribe(data => {
                if (data) {
                    this.saveSuccess = true;
                }
                else {
                    this.saveSuccess = false;
                }
            },
                error => this.errors = error,
                () => this.res = 'Completed'
            );
    }

任何提示都會有用。

問候,-Alan-

您無法使此異步調用同步。 但是你可以利用observable來等待文件被讀取:

//when the submit button is clicked
onSubmit = () => {
    let file = Observable.create((observer) => {
        let fr = new FileReader();
        let data = new Blob([this.attachment]);
        fr.readAsArrayBuffer(data);
        fr.onloadend = () => {
            observer.next(fr.result);
            observer.complete()
        };
        fr.onerror = (err) => {
            observer.error(err)
        }
        fr.onabort = () => {
            observer.error("aborted")
        }
    });
    file.map((fileData) => {
            //build the attachment object which will be sent to Web API
            let attachment: Attachment = {
                AttachmentId: '0',
                FileName: this.form.controls["attachmentName"].value,
                FileData: fileData
            }
            //build the purchase order object
            let order: UpdatePurchaseOrder = {
                SendEmail: true,
                PurchaseOrderNumber: this.form.controls["purchaseOrderNumber"].value,
                Attachment: attachment
            }
            return order;
        })
        .switchMap(order => this.updatePoService.updatePurchaseOrder(this.form.controls["purchaseOrderRequestId"].value, order))
        .subscribe(data => {
                if (data) {
                    this.saveSuccess = true;
                } else {
                    this.saveSuccess = false;
                }
            },
            error => this.errors = error,
            () => this.res = 'Completed'
        );
}

我到這里尋找類似問題的解決方案。 我正在向端點執行請求,如果出現任何問題,它可以響應二進制blob,或者出現錯誤時可以響應JSON文件。

this.httpClient.post(urlService, bodyRequest,
      {responseType: 'blob', headers: headers})
.pipe(map((response: Response) => response), 
catchError((err: Error | HttpErrorResponse) => {
      if (err instanceof HttpErrorResponse) {
// here, err.error is a BLOB containing a JSON String with the error message
      } else {
        return throwError(ErrorDataService.overLoadError(err, message));
      }
}));

由於FileReaderSync顯然在Angular6中不起作用,我在解析Blob內容后使用n00dl3的解決方案(上面)拋出錯誤:

return this.httpClient.post(urlService, bodyRequest,
      {responseType: 'blob', headers: headers})
.pipe(map((response: Response) => response), 
catchError((err: Error | HttpErrorResponse) => {
  const message = `In TtsService.getTts(${locale},${outputFormat}). ${err.message}`;
  if (err instanceof HttpErrorResponse) {
    const $errBlobReader: Observable<HttpErrorResponse> = Observable.create((observer) => {
      const fr = new FileReader();
      const errorBlob = err.error;
      fr.readAsText(errorBlob, 'utf8');
      fr.onloadend = () => {
        const errMsg =  JSON.parse(fr.result).message;
        const msg = `In TtsService.getTts(${locale},${outputFormat}). ${errMsg}`;
        observer.error(ErrorDataService.overLoadError(err, msg));
      };
      fr.onerror = (blobReadError) => {
        observer.error(blobReadError);
      };
      fr.onabort = () => {
        observer.error('aborted');
      };
    });
    return $errBlobReader;
  } else {
    return throwError(ErrorDataService.overLoadError(err, message));
  }
}));

謝謝! 你真的救了我的一天!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM