Last active
February 23, 2021 18:43
-
-
Save NathanWalker/0ecbe1158058c48cf96dcfe2fa7e4520 to your computer and use it in GitHub Desktop.
Simple offline handling with NativeScript using Angular as example
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
// pseudo code using angular flavor as example | |
@Injectable({ providedIn: 'root' }) | |
export class SomeHttpInterceptor implements HttpInterceptor { | |
_mobileOffline = new MobileOffline(); | |
constructor(private mobileStorage: MobileAPIStorageService) {} | |
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | |
if (!this._mobileOffline.isOnline) { | |
// Offline | |
// cached responses only | |
return this.mobileStorage | |
.getItem(cacheKey) | |
.pipe( | |
take(1), | |
map((res) => { | |
return new HttpResponse({ | |
body: res, | |
status: 200, | |
url: req.url, | |
}); | |
}) | |
); | |
} else { | |
return next.handle(req).pipe( | |
tap((event: HttpEvent<any>) => { | |
if (event instanceof HttpResponse) { | |
if (req.method && req.method.toLowerCase() === 'get') { | |
// cache all get requests for right now | |
// NOTE: you can provide your own configurations around this | |
this.mobileStorage.setItem(this._getRequestCacheKey(req), event.body); | |
} | |
} | |
}), | |
catchError((err: any) => { | |
console.log('catch http error:', err); | |
return throwError(err); | |
}) | |
); | |
} | |
} | |
private _getRequestCacheKey(req: HttpRequest<any>) { | |
return `${req.method}-${req.urlWithParams}`; | |
} | |
} |
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 } from '@angular/core'; | |
import { ApplicationSettings } from '@nativescript/core'; | |
@Injectable({ providedIn: 'root' }) | |
export class MobileAPIStorageService { | |
public setItem(key: string, data: any): void { | |
if (typeof data === 'undefined') { | |
data = null; | |
} else { | |
data = JSON.stringify(data); | |
} | |
ApplicationSettings.setString(key, data); | |
} | |
public getItem(key: string, _default = null): Observable<any> { | |
const item = ApplicationSettings.getString(key); | |
if (!item || item === 'null') { | |
return from(Promise.resolve(_default)); | |
} | |
try { | |
return from(Promise.resolve(JSON.parse(item))); | |
} catch (e) { | |
return from(Promise.resolve(_default)); | |
} | |
} | |
public removeItem(key: string): void { | |
ApplicationSettings.remove(key); | |
} | |
public clearAll(): void { | |
ApplicationSettings.clear(); | |
} | |
} |
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 { Connectivity } from '@nativescript/core'; | |
export class MobileOffline { | |
isOnline = true; | |
constructor() { | |
this._init(); | |
} | |
private _init() { | |
// IMPORTANT: This works inconsistently between Simulator and real device | |
// * Simulator: will fire when going Offline, but never again when user comes back online | |
// * real device: will fire properly in both cases so don't worry about the simulator case | |
Connectivity.startMonitoring((networkType) => { | |
let isOnline = false; | |
switch (networkType) { | |
case Connectivity.connectionType.none: | |
// no connection | |
isOnline = false; | |
break; | |
case Connectivity.connectionType.wifi: | |
case Connectivity.connectionType.mobile: | |
// wifi or cellular data | |
isOnline = true; | |
break; | |
default: | |
// assume offline in unknown cases | |
isOnline = false; | |
break; | |
} | |
console.log(`monitoring connectivity, connectionType: ${networkType}, isOnline: ${isOnline}`); | |
// if first time going offline, show notice | |
if (this.isOnline && !isOnline) { | |
// show offline notice here only once, the first time user goes from online > offline | |
// toast message or whatever | |
} | |
this.isOnline = isOnline; | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment