Created
January 12, 2021 11:29
-
-
Save vaibhavgehani/9d037f3cb216bf25e4c4180ce3cad8d4 to your computer and use it in GitHub Desktop.
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 { HttpClient } from '@angular/common/http'; | |
import { Injectable } from '@angular/core'; | |
import { environment } from '@env/environment'; | |
import { Network } from '@ionic-native/network/ngx'; | |
import { AlertController, Platform } from '@ionic/angular'; | |
import { Storage } from '@ionic/storage'; | |
import { forkJoin, from, Observable, of } from 'rxjs'; | |
import { finalize, switchMap } from 'rxjs/operators'; | |
import { StoredRequest } from '../../models/request'; | |
@Injectable({ | |
providedIn: 'root' | |
}) | |
export class APIManager { | |
disconnectSubscription: any; | |
connectSubscription: any; | |
networkAlert: HTMLIonAlertElement; | |
networkStatus = true; | |
requestSubscriber: any; | |
mutex = true; | |
constructor( | |
private storage: Storage, | |
private http: HttpClient, | |
private network: Network, | |
private platform: Platform, | |
private alertCtrl: AlertController | |
) { | |
this.platform.ready().then(() => { | |
this.checkInternetConnection(); | |
}); | |
} | |
async checkInternetConnection() { | |
this.disconnectSubscription = this.network.onDisconnect().subscribe(async () => { | |
this.mutex = true; | |
this.networkAlert = await this.createNetworkAlert('No Internet', false, 'Please Check you internet Connection and try again',{ | |
text: 'Ok.!, Checking', | |
role: '', | |
cssClass: 'secondary', | |
handler: async () => { | |
this.networkAlert.dismiss(); | |
this.networkAlert = null; | |
} | |
}); | |
this.networkAlert.present(); | |
this.networkStatus = false; | |
}); | |
this.connectSubscription = this.network.onConnect().subscribe(() => { | |
this.networkStatus = true; | |
if(this.networkAlert) { | |
this.networkAlert.dismiss(); | |
this.networkAlert = null; | |
} | |
if (this.mutex) { | |
this.mutex = false; | |
this.requestSubscriber = this.checkForUnCompleteAPI().subscribe(); | |
} | |
}); | |
} | |
checkForUnCompleteAPI(): Observable <any> { | |
return from(this.storage.get(environment.REQ_STORAGE_KEY)).pipe( | |
switchMap((storedOperations: any) => { | |
let storedObj = JSON.parse(storedOperations); | |
if (storedObj && storedObj.length > 0) { | |
return this.sendRequests(storedObj).pipe( | |
finalize(() => { | |
this.completeAllRequests().then(async () => { | |
this.requestSubscriber.unsubscribe(); | |
const stored = await this.storage.get(environment.REQ_STORAGE_KEY); // use the db name that you prefer | |
}); | |
}) | |
); | |
} else { | |
return of(false); | |
} | |
}) | |
) | |
} | |
completeAllRequests(): Promise <any> { | |
return new Promise((resolve, reject) => { | |
this.storage.get(environment.REQ_STORAGE_KEY).then((StoredReqs) => { | |
let storedObj = JSON.parse(StoredReqs); | |
storedObj.forEach((request) => { | |
request.completed = true; | |
}); | |
this.storage.remove(environment.REQ_STORAGE_KEY); | |
resolve(this.storage.set(environment.REQ_STORAGE_KEY, JSON.stringify(storedObj))); | |
}); | |
}) | |
} | |
storeCallAndRespond(method, url, header, data?): Promise <any> { | |
return new Promise(async (resolve, reject) => { | |
const action: StoredRequest = { | |
url: url, | |
type: method, | |
data: data ? data : null, | |
time: new Date().getTime(), | |
completed: false, | |
response: null, | |
header: header, | |
id: Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5) | |
}; | |
const Store = await this.storeRequest(action); | |
await this.repeatRequest(action).then((response) => { | |
console.log('Response', response); | |
resolve(response); | |
}) | |
}); | |
} | |
async repeatRequest(action) { | |
return new Promise(async (resolve, reject) => { | |
let response; | |
if (!this.networkStatus) { | |
// No Internet | |
resolve(action.data); | |
} else { | |
// Internet is there | |
if (action.type === 'GET') { | |
response = await this.http.request(action.type, action.url, {headers: action.header}).toPromise(); | |
} else { | |
response = await this.http.request(action.type, action.url, {body: action.data, headers: action.header}).toPromise(); | |
} | |
this.updateActionObject(action, response); | |
resolve(response); | |
} | |
}); | |
} | |
storeRequest(action) { | |
this.storage.get(environment.REQ_STORAGE_KEY).then((storedOperations) => { | |
let storedObj = JSON.parse(storedOperations); | |
if (storedObj) { | |
storedObj.push(action); | |
} else { | |
storedObj = [action]; | |
} | |
return this.storage.set(environment.REQ_STORAGE_KEY, JSON.stringify(storedObj)); | |
}); | |
} | |
updateActionObject(action, response) { | |
this.storage.get(environment.REQ_STORAGE_KEY).then((storedOperations) => { | |
let storedObj = JSON.parse(storedOperations); | |
storedObj.forEach((call) => { | |
if (call.id == action.id) { | |
call.response = response; | |
call.completed = true; | |
} | |
}); | |
this.storage.remove(environment.REQ_STORAGE_KEY); | |
return this.storage.set(environment.REQ_STORAGE_KEY, JSON.stringify(storedObj)); | |
}); | |
} | |
sendRequests(operations: StoredRequest[]) { | |
console.log('Req Called') | |
let obs = []; | |
let oneObs; | |
for (let op of operations) { | |
if (!op.completed) { | |
if (op.type === 'GET') { | |
oneObs = this.http.request(op.type, op.url, {headers: op.header}); | |
} else { | |
oneObs = this.http.request(op.type, op.url, {body: op.data, headers: op.header}); | |
} | |
console.log('Array res', oneObs); | |
obs.push(oneObs); | |
} | |
} | |
return forkJoin(obs); | |
} | |
ngOnDestroy() { | |
this.disconnectSubscription.unsubscribe(); | |
this.connectSubscription.unsubscribe(); | |
} | |
async createNetworkAlert(header, backdropDismiss, message, buttonOptions1, buttonOptions2?): Promise<HTMLIonAlertElement> { | |
const alert = await this.alertCtrl.create({ | |
header, | |
backdropDismiss, | |
message, | |
buttons: !buttonOptions2 ? [buttonOptions1] : [buttonOptions1, buttonOptions2] | |
}); | |
return alert; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment