Last active
November 28, 2023 17:08
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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