Angular 5 manage http get with blob response and json errors Angular 5 manage http get with blob response and json errors typescript typescript

Angular 5 manage http get with blob response and json errors


This is a known Angular issue, and in that thread JaapMosselman provides a very nice solution that involves creating an HttpInterceptor which will translate the Blob back to JSON.

Using this approach, you don't have to do conversions throughout your application, and when the issue is fixed, you can simply remove it.

import { Injectable } from '@angular/core';import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpErrorResponse } from '@angular/common/http';import { Observable, throwError } from 'rxjs';import { catchError } from 'rxjs/operators';@Injectable()export class BlobErrorHttpInterceptor implements HttpInterceptor {    public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {        return next.handle(req).pipe(            catchError(err => {                if (err instanceof HttpErrorResponse && err.error instanceof Blob && err.error.type === "application/json") {                    // https://github.com/angular/angular/issues/19888                    // When request of type Blob, the error is also in Blob instead of object of the json data                    return new Promise<any>((resolve, reject) => {                        let reader = new FileReader();                        reader.onload = (e: Event) => {                            try {                                const errmsg = JSON.parse((<any>e.target).result);                                reject(new HttpErrorResponse({                                    error: errmsg,                                    headers: err.headers,                                    status: err.status,                                    statusText: err.statusText,                                    url: err.url                                }));                            } catch (e) {                                reject(err);                            }                        };                        reader.onerror = (e) => {                            reject(err);                        };                        reader.readAsText(err.error);                    });                }                return throwError(err);            })        );    }}

Declare it in your AppModule or CoreModule:

import { HTTP_INTERCEPTORS } from '@angular/common/http';...@NgModule({    ...    providers: [        {            provide: HTTP_INTERCEPTORS,            useClass: BlobErrorHttpInterceptor,            multi: true        },    ],    ...export class CoreModule { }


Like probably most people, I wanted my error message synchronously. I dealt with the problem by putting it in an alert box:

(err:any) => {     // Because result, including err.error, is a blob,    // we must use FileReader to display it asynchronously:    var reader = new FileReader();    reader.onloadend = function(e) {      alert("Error:\n" + (<any>e.target).result);    }    reader.readAsText(err.error);    let errorMessage = "Error: " + err.status.toString() + " Error will display in alert box.";    // your code here to display error messages.},


As in docs "The only way to read content from a Blob is to use a FileReader." https://developer.mozilla.org/en-US/docs/Web/API/Blob.

EDIT:If you need part of blob, you can do a slice, which returns new Blob,and then use file reader.