Skip to content

Instantly share code, notes, and snippets.

@raco
Last active November 28, 2023 17:08
Show Gist options
  • Save raco/e05e1ca11bcb705c2b2d88fc79c62fb5 to your computer and use it in GitHub Desktop.
Save raco/e05e1ca11bcb705c2b2d88fc79c62fb5 to your computer and use it in GitHub Desktop.
Interceptor + Provider, transform Angular http to Capacitor's http, so if web uses Angular http else Capacitor's http
import { Injectable, Provider } from '@angular/core';
import {
HTTP_INTERCEPTORS,
HttpErrorResponse,
HttpEvent,
HttpHandler,
HttpHeaders,
HttpInterceptor,
HttpParams,
HttpRequest,
HttpResponse
} from '@angular/common/http';
import {
CapacitorHttp as Http,
HttpParams as CapacitorHttpParams,
HttpHeaders as CapacitorHttpHeaders
} from '@capacitor/core';
import { Platform } from '@ionic/angular';
import { defer, Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class CapacitorHttpInterceptor implements HttpInterceptor {
constructor(private platform: Platform) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.platform.is('capacitor')) {
return this.interceptNativeRequest(req, next);
}
return this.interceptWebRequest(req, next);
}
private interceptNativeRequest(req: HttpRequest<any>, _next: HttpHandler): Observable<HttpEvent<any>> {
const { method, body, url, headers, params } = req;
/**
* Transforms the type signature of Angular http headers
* to Capacitor's type signature for http headers.
*
* Sanitizes invalid header values from the output.
*/
const sanitizeHeaders = (_headers: HttpHeaders) => {
const res: CapacitorHttpHeaders = {};
for (const key of _headers.keys()) {
res[key] = decodeURIComponent(params.get(key) || '');
}
return res;
};
/**
* Transforms the type signature of Angular http params
* to Capacitor's type signature for http params.
*
* Sanitizes invalid param values from the output.
*/
const sanitizeParams = (_params: HttpParams) => {
const res: CapacitorHttpParams = {};
for (const key of _params.keys()) {
res[key] = decodeURIComponent(_params.get(key) || '');
}
return res;
};
return defer(() =>
Http.request({
url,
method,
data: body || method === 'GET' ? undefined : {},
headers: {
...sanitizeHeaders(headers),
Accept: 'application/json',
'Content-Type': 'application/json'
},
params: sanitizeParams(params)
})
).pipe(
catchError((e) => throwError(() => this.handleRequestError(e))),
map((res) => {
if (res.status >= 400) {
const errorResponse = new HttpErrorResponse({
error: res.data,
headers: new HttpHeaders(res.headers),
url: res.url,
status: res.status
});
throw this.handleRequestError(errorResponse);
}
return new HttpResponse({ body: res.data });
})
);
}
private interceptWebRequest(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req);
}
private handleRequestError(error: HttpErrorResponse) {
return error;
}
}
/**
* Provider you can add it to your ApplicationConfig in main.ts
*/
export const CapacitorHttpProvider: Provider = {
provide: HTTP_INTERCEPTORS,
useClass: CapacitorHttpInterceptor,
multi: true
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment