angular2 http中间件与rxjs

时间:2016-08-30 00:43:30

标签: angular rxjs

我使用angular2并拥有ApiService ...完整的课程如下......



import {Store} from '@ngrx/store';
import { Injectable } from '@angular/core';
import { Headers, RequestOptions, Http } from '@angular/http';
import {AppState} from '../app.store';
import { Observable } from 'rxjs/Observable';
import {AuthActions} from '../actions/AuthActions';

@Injectable()
export class ApiService {

  private currentState: AppState;

  constructor(
    private store: Store<AppState>,
    private http: Http
  ) {
    // get config once...
    store.subscribe((state:AppState) => {
      this.currentState = state;
    });
  }

  // PUBLIC

  /*
  --  POST
   */
  post(path:string, payload:Object) {

    let request = this.http.post(
      this.getEndpoint(path),
      JSON.stringify(payload),
      this.getHeaderOptions('post')
    );

    // DOESN'T WORK... fires http twice
    // this.responseMiddleware(request);

    return request;
  }

  /*
   --  GET
   */
  get(path:string) {

    let request = this.http.get(
      this.getEndpoint(path),
      this.getHeaderOptions('get')
    );

    return request;
  }

  /*
   --  DELETE
   */
  delete(path:string) {

    let request = this.http.delete(
      this.getEndpoint(path),
      this.getHeaderOptions('delete')
    );

    return request;

  }

  // PROCESS ALL REQUESTS LOOKING FOR BAD STUFF ??
  // HOW to subscribe without firing http 2x ??
  // private responseMiddleware(request:Observable<any>) {
  //   request.subscribe(
  //     (res) => {},
  //     (err) => {
  //       // catch error
  //       if(err.status === 401) {
  //         // unorthorised
  //         this.store.dispatch({type:AuthActions.AUTHENTICATE_DELETE});
  //       }
  //     },
  //     () => {}
  //   );
  // }

  // GET ENDPOINT FROM CONFIG FILE
  private getEndpoint(path:string) {
    if(!this.currentState.config.file.endpoint) {
      throw new Error('========= CONFIG NOT SET =========');
    }
    return this.currentState.config.file.endpoint + path;
  }

  // PUT TOGETHER CORRECT HEADER OBJECT BASED ON REQUEST TYPE
  private getHeaderOptions(type:string = 'get') {

    let headersObj:any = {
      'Accept'          : 'application/json',
      'X-Lc-Svc-Channel': 'lc-web-product'
    };

    switch(type) {
      case 'post':
        headersObj['Content-Type'] = 'application/json';
        break;
      default:
        break;
    }

    let token = this.currentState.auth.token;
    if(token) {
      headersObj.Authorization = token;
    }

    return new RequestOptions({ headers: new Headers(headersObj)});

  }
}
&#13;
&#13;
&#13;

我想要做的是在每个请求上都有某种中间件来监听状态代码......但是我尝试的解决方案(订阅http observable)会激活http请求两次。

如果没有这种情况,我怎么能这样做?

1 个答案:

答案 0 :(得分:2)

对于任何有兴趣的人,我目前已经解决了这个问题,每个请求类型都会catch。我确信有更好的方法......如果你能想到一个我想知道的但现在有效的方法。

get(path:string) {

  let request = this.http.get(
    this.getEndpoint(path),
    this.getHeaderOptions('get')
  ).catch((err:any) => {
    if(err.status === 401) {
      this.store.dispatch({type:AuthActions.AUTHENTICATE_DELETE});
      return Observable.of('Not authenticated');
    }
    return err;
  });

  return request;
}