How to use angular2 http API for tracking upload/download progress

前端 未结 2 1874
梦如初夏
梦如初夏 2020-12-07 23:32

Tho there are many adhoc libraries supporting upload/download progress in angular2, I do not know how to do use native angular2 http api to show progress while doing upload/

相关标签:
2条回答
  • 2020-12-07 23:47

    As of Angular 4.3.x and beyond versions, it can be achieved using the new HttpClient from @angular/common/http.

    Read the Listening to progress events section.

    Simple upload example (copied from the section mentioned above):

    const req = new HttpRequest('POST', '/upload/file', file, {
      reportProgress: true,
    });
    
    http.request(req).subscribe(event => {
      // Via this API, you get access to the raw event stream.
      // Look for upload progress events.
      if (event.type === HttpEventType.UploadProgress) {
        // This is an upload progress event. Compute and show the % done:
        const percentDone = Math.round(100 * event.loaded / event.total);
        console.log(`File is ${percentDone}% uploaded.`);
      } else if (event instanceof HttpResponse) {
        console.log('File is completely uploaded!');
      }
    });
    

    And for downloading, it might be something like pretty much the same:

    const req = new HttpRequest('GET', '/download/file', {
      reportProgress: true,
    });
    
    http.request(req).subscribe(event => {
      // Via this API, you get access to the raw event stream.
      // Look for download progress events.
      if (event.type === HttpEventType.DownloadProgress) {
        // This is an download progress event. Compute and show the % done:
        const percentDone = Math.round(100 * event.loaded / event.total);
        console.log(`File is ${percentDone}% downloaded.`);
      } else if (event instanceof HttpResponse) {
        console.log('File is completely downloaded!');
      }
    });
    

    Remember in case that you're monitoring a download, the Content-Length has to be set, otherwise, there's no way to the request to be measured.

    0 讨论(0)
  • 2020-12-07 23:57

    I would suggest using the native JavaScript XHR wrapped as an Observable, it's fairly easy to create on your own:

    upload(file: File): Observable<string | number> {
    
        let fd: FormData = new FormData();
    
        fd.append("file", file);
    
        let xhr = new XMLHttpRequest;
    
        return Observable.create(observer => {
    
            xhr.addEventListener("progress", (progress) => {
    
                let percentCompleted;
    
                // Checks if we can really track the progress
                if (progress.lengthComputable) {
    
                    // progress.loaded is a number between 0 and 1, so we'll multiple it by 100
                    percentCompleted = Math.round(progress.loaded / progress.total * 100);
    
                    if (percentCompleted < 1) {
                        observer.next(0);
                    } else {
                        // Emit the progress percentage
                        observer.next(percentCompleted);
                    }
                }
            });
    
            xhr.addEventListener("load", (e) => {
    
                if (e.target['status'] !== 200) observer.error(e.target['responseText']);
    
                else observer.complete(e.target['responseText']);
            });
    
            xhr.addEventListener("error", (err) => {
    
                console.log('upload error', err);
    
                observer.error('Upload error');
            });
    
            xhr.addEventListener("abort", (abort) => {
    
                console.log('upload abort', abort);
    
                observer.error('Transfer aborted by the user');
            });
    
            xhr.open('POST', 'http://some-dummy-url.com/v1/media/files');
    
            // Add any headers if necessary
            xhr.setRequestHeader("Authorization", `Bearer rqrwrewrqe`);
    
            // Send off the file
            xhr.send(fd);
    
            // This function will get executed once the subscription
            // has been unsubscribed
            return () => xhr.abort()
        });
    }
    

    And this is how one would use it:

    // file is an instance of File that you need to retrieve from input[type="file"] element
    const uploadSubscription = this.upload(file).subscribe(progress => {
        if (typeof progress === Number) {
            console.log("upload progress:", progress);
        }
    });
    
    // To abort the upload
    // we should check whether the subscription is still active
    if (uploadSubscription) uploadSubscription.unsubscribe();
    
    0 讨论(0)
提交回复
热议问题