'Why Interceptor not working with capacitor-community/http?
My problem is that my interceptors not working with library capacitor-community/http
.
I develop my app in Ionic and how can you see I provide interceptor in module. This is really problem with this library because my interceptors working with HttpClient from angular. More you can see in codes and images.
Interceptor:
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(
private authService: AuthService,
) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log("I am here");
return next.handle(request).pipe(
catchError(err => {
const error = err.message || err.statusText;
return throwError(error);
})
);
}
}
calling method:
this.authService.login(item.username, item.password).pipe(
finalize(() => {
console.log("end");
}),
).subscribe();
service with @capacitor-community/http: enter image description here
login(username: string, password: string): Observable<any> {
const options = {
url:this.resourceUrl + "/login",
data: {
username: username,
password: password
},
headers: { 'Content-Type': 'application/json' }
};
return from(Http.post(options));
}
service with httpClient from @angular/common/http: enter image description here
login(username: string, password: string): Observable<any> {
return this.http.post<any>(this.resourceUrl + "/login", { username, password });
}
appModule:
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
HttpClientModule,
IonicModule.forRoot(),
AppRoutingModule,
],
providers: [
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
],
bootstrap: [AppComponent],
})
Solution 1:[1]
I had the same issue, the way I "hacked" it is: use the navite http only for the login or your very first request which is usually anonymous, after that use the angular http and the interceptor works without any CORS issues. However the best approach would be to have the interceptor specifically built for capaitor http
Solution 2:[2]
The solution that worked for me was to use the normal Angular HttpClient and switch to the plugin in the very last interceptor, similar to how you can mock a backend:
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpInterceptor, HttpResponse, HttpEvent, HttpHeaders
} from '@angular/common/http';
import { Observable, from } from 'rxjs';
import { Http } from "@capacitor-community/http";
import { map } from "rxjs/internal/operators";
@Injectable()
export class NativeHttpInterceptor implements HttpInterceptor {
constructor() {}
private static toHttpResponse(capResponse: any): HttpResponse<unknown> {
return new HttpResponse({
status: capResponse.status,
headers: new HttpHeaders(capResponse.headers),
url: capResponse.url,
body: capResponse.data
})
}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<any>> {
// to make an exception for local fetches like i18n assets
if (!request.url.includes("https://"))
return next.handle(request)
const headers = request.headers.keys().reduce((o, key) => ({ ...o, [key]: request.headers.get(key) }), {})
const params = request.params.keys().reduce((o, key) => ({ ...o, [key]: request.params.get(key) }), {})
let options: any = { url: request.url, responseType: request.responseType, headers, params }
switch (request.method) {
case "GET":
return from(Http.get(options)).pipe(
map<any, HttpResponse<unknown>>(capResponse => NativeHttpInterceptor.toHttpResponse(capResponse))
)
case "POST":
options = { ...options, data: request.body }
return from(Http.post(options)).pipe(
map<any, HttpResponse<unknown>>(capResponse => NativeHttpInterceptor.toHttpResponse(capResponse))
)
case "PUT":
options = { ...options, data: request.body }
return from(Http.put(options)).pipe(
map<any, HttpResponse<unknown>>(capResponse => NativeHttpInterceptor.toHttpResponse(capResponse))
)
default:
throw new TypeError(`Invalid HTTP method: ${request.method}`)
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | S.Minchev |
Solution 2 | mistrrose |