Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Angular2でHttpInterceptorが欲しいお

Angular2 HttpInterceptor Needed

Who am I

  • 小川充
    • @mitsuruog
    • Front-end Developer in Givery inc.
    • Angular User Group Staff.

HttpInterceptorとは

  • XHRに関連する横断的機能(cross-cutting)を分離する
    • Global Error handling
    • Fail back to show notification
  • Angular1ではHttpInterceptorを使うことで、これらを綺麗に分離できた

How about a httpInterceptor in Angular 2 ?

結論

簡単にできない!!

Way of httpInterceptor in Angular 2

following step

  1. 既存のHttpをOverrideするためのCustomHttpサービスを作成する
  2. bootstrapで既存のHttpをOverideする

Create a CustomHttp service

custom-http.service.ts

import {Http, ConnectionBackend, RequestOptions, Request, RequestOptionsArgs, Response} from "angular2/http";
import {Observable} from "rxjs/Observable";

export class CustomHttp extends Http {

    constructor(backend:ConnectionBackend,
                defaultOptions:RequestOptions) {
        super(backend, defaultOptions)
    }

    request(url:string | Request, options?:RequestOptionsArgs):Observable<Response> {
        return super.request(url, options).catch((res: Response) => this.handleResponseError(res));
    }

    get(url:string, options?:RequestOptionsArgs):Observable<Response> {
        return super.get(url, options).catch((res: Response) => this.handleResponseError(res));
    }

    // ...長いので省略
    
    //
    // Here's to handle error stuff
    // 
    private handleResponseError(res:Response) {
        if (res.status === 401) {
          // do something
        } else if (res.status === 500) {
          // do something
        }
        return Observable.throw(res);
    }
}

全体像はこちらを見てください。
custom-http.service.ts

Override Http to CustomHttp at bootstrap

main.ts

import 'rxjs/Rx';

import {bootstrap} from 'angular2/platform/browser';
import {provide} from "angular2/core";

import {AppComponent} from './app.component';
import {CustomHttp} from "./common/services/custom-http.service";

bootstrap(AppComponent, [
    provide(Http, {
        useFactory: (backend:XHRBackend, defaultOptions:RequestOptions) => {
            return new CustomHttp(backend, defaultOptions)
        },
        deps: [XHRBackend, RequestOptions]
    })
]);

⚠️
Angular2はRxJSのAPIをWarpしているが、RxJSのすべてのAPIを提供していない。
RsJSのAPIをフルで利用したい場合は、main.tsRxJSを直接importする必要がある。
main.ts

import 'rxjs/Rx';


## Conclusion

- Angualr2でもAngular1のHttpInterceptorと近いことはできる。
- ただ、少し面倒だ。
  - 使えそうなもの置いておきます => [custom-http.service.ts](https://gist.github.com/mitsuruog/6f7f0ca3f546b245bccdd3ebc14375d8#file-custom-http-service-ts) 
import {Http, ConnectionBackend, RequestOptions, Request, RequestOptionsArgs, Response} from "angular2/http";
import {Observable} from "rxjs/Observable";
export class CustomHttp extends Http {
constructor(backend:ConnectionBackend, defaultOptions:RequestOptions) {
super(backend, defaultOptions)
}
request(url:string | Request, options?:RequestOptionsArgs):Observable<Response> {
return super.request(url, options).catch((res: Response) => this.handleResponseError(res));
}
get(url:string, options?:RequestOptionsArgs):Observable<Response> {
return super.get(url, options).catch((res: Response) => this.handleResponseError(res));
}
post(url:string, body:string, options?:RequestOptionsArgs):Observable<Response> {
return super.post(url, body, options).catch((res: Response) => this.handleResponseError(res))
}
put(url:string, body:string, options?:RequestOptionsArgs):Observable<Response> {
return super.put(url, body, options).catch((res: Response) => this.handleResponseError(res));
}
delete(url:string, options?:RequestOptionsArgs):Observable<Response> {
return super.delete(url, options).catch((res: Response) => this.handleResponseError(res));
}
patch(url:string, body:string, options?:RequestOptionsArgs):Observable<Response> {
return super.patch(url, body, options).catch((res: Response) => this.handleResponseError(res));
}
head(url:string, options?:RequestOptionsArgs):Observable<Response> {
return super.head(url, options).catch((res: Response) => this.handleResponseError(res));
}
private handleResponseError(res:Response) {
console.log(res);
if (res.status === 401) {
// do something
} else if (res.status === 500) {
// do something
}
return Observable.throw(res);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment