2016-12-12 2 views
2

Я следовал за статьей this, чтобы расширить поставщика Http и создать собственный пользовательский поставщик Http. Теперь я пытаюсь поймать все исключения сервера и в зависимости от кода состояния необходимо предпринять соответствующие действия.Расширение Angular2 Http провайдера и сервера обработки

http.service.ts:

 @Injectable() 
export class HttpService extends Http { 

    constructor(backend: XHRBackend, options: RequestOptions) { 
     let token = localStorage.getItem('auth_token'); // your custom token getter function here 
     options.headers.set('Authorization', `Bearer ${token}`); 
     super(backend, options); 
    } 

    request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> { 
     let token = localStorage.getItem('auth_token'); 
     if (typeof url === 'string') { // meaning we have to add the token to the options, not in url 
      if (!options) { 
       // let's make option object 
       options = { headers: new Headers() }; 
      } 
      options.headers.set('Authorization', `Bearer ${token}`); 
     } else { 
      // we have to add the token to the url object 
      url.headers.set('Authorization', `Bearer ${token}`); 
     } 
     return super.request(url, options).catch(this.catchAuthError(this)); 
    } 

    private catchAuthError(self: HttpService) { 
     //I want to execute this function whenever there is any error from the server, 
     //but control is not coming here. 
     return (res: Response) => { 
      console.log("This is from the proxy http", res); 
      if (res.status === 401 || res.status === 403) { 
       // if not authenticated 
       console.log("Do something"); 
      } 
      return Observable.throw(res); 
     }; 
    } 
} 

Assets.service.ts:

import { HttpService } from './http.service'; 
@Injectable() 
export class DataService { 
    constructor(private _http: HttpService) { 
     login(userName: string, password: string) { 
      const headers = new Headers(); 
      headers.append("Authorization", 'Basic ' + btoa(userName + ":" + password)); 
      headers.append("Content-Type", 'text/plain'); 
      const requestUrl = this.loginResource + userName; 
      return this._http.get(requestUrl, { headers: headers }) 
       .map((response: Response) => { 
        let res = response.json(); 
        this.token = response.headers.get('token') 
        return res; 
       }); 
     } 
    } 
} 

app.module.ts:

import { HttpService } from './services/http.service'; 
@NgModule({ 
    imports: [BrowserModule, HttpModule, ...], 
    declarations: [...], 
    providers: [ 
     { provide: LocationStrategy, useClass: HashLocationStrategy }, 
     { 
      provide: HttpService, 
      useFactory: (backend: XHRBackend, options: RequestOptions) => { 
       return new HttpService(backend, options); 
      }, 
      deps: [XHRBackend, RequestOptions] 
     } 
    ], 

    bootstrap: [AppComponent], 
}) 

export class AppModule { 
} 

EDIT: Мой пользовательский поставщик Http не делает xhr-звонки, instaed даже после расширения http, он все еще вызывает встроенный http.request.

Я создал plnkr, и пользовательский Http-вызов работает там, но не в моем локальном коде (xhr звонки работают, но встроенный - не пользовательский). Не уверен, что именно противоречит местному коду.

ответ

0
return super.request(url, options).catch(this.catchAuthError(this)); 

должно быть

return super.request(url, options).catch(this.catchAuthError.bind(this)); 

или

return super.request(url, options).catch((err) => this.catchAuthError(err)); 

и

private catchAuthError (self: HttpService) { 

должно быть

private catchAuthError (err) { 
+0

Это также не работает. –

+0

Служба выполняет файл http.request() по умолчанию, а не тот, который я расширил. Итак, строка: return super.request (url, options) .catch (this.catchAuthError.bind (this)); никогда не выполняется. –

+0

Изменить 'обеспечить: HttpService', чтобы' обеспечить: Http' –

Смежные вопросы