Расширение Angular2 Http-провайдера и сервера обработки

Я следовал этой статье, чтобы расширить поставщика HTTP и создал мой собственный пользовательский 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);
        };
    }
}

Активы.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, даже после расширения http, он все еще вызывает встроенный http.request.

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


person Saurabh Palatkar    schedule 12.12.2016    source источник


Ответы (2)


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

должно быть

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

or

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

а также

private catchAuthError (self: HttpService) {

должно быть

private catchAuthError (err) {
person Günter Zöchbauer    schedule 12.12.2016
comment
Служба выполняет http.request() по умолчанию, а не тот, который я расширил. Итак, строка: return super.request(url, options).catch(this.catchAuthError.bind(this)); никогда не казнят. - person Saurabh Palatkar; 13.12.2016
comment
Изменить provide: HttpService на provide: Http - person Günter Zöchbauer; 13.12.2016

Укажите свой расширенный класс как значение useClass:

{   
    provide : Http,
    useClass:AppHTTPInterceptor,
    deps: [XHRBackend, RequestOptions, AnyOtherService]
},

AnyOtherService не должен зависеть от Http, иначе это приведет к ошибке циклической зависимости.

person Sumudu    schedule 06.04.2018