I’m struggling to get my head around promises and I could really use some help.
This is my desired behaviour for my app:
- User can create multiple data records and save them in local storage (when no connectivity present)
- When connectivity is present, user can click the “Upoad” button, which will grab all local storage records and for each record it will do the following:
** Push data item to existing online database
** Delete data item from existing local storage records
For example, if I had 3 local records then I would want the code to execute things in the following order:
- Display “Uploading” loading dialogue
-
Upload data item #1 to online DB
* [Wait for upload to complete] -
Delete data item #1 from local storage
* [Wait for delete complete] -
Upload data item #2 to online DB
* [Wait for upload to complete] -
Delete data item #2 from local storage
* [Wait for delete complete] -
Upload data item #3 to online DB
* [Wait for upload to complete] -
Delete data item #3 from local storage
* [Wait for delete complete] - Dismiss “Uploading” loading dialogue
Below is an example of the code i’m trying to use. For the purposes of this forum post, local storage is simply “local-db” and online storage is simply another instance of local storage called “online-db”.
uploadLocalData_Promise(){
return new Promise((resolve, reject) => {
this.getData_Promise('local-db').then((localDataArray: any) => {
localDataArray.forEach((localDataObject) => {
this.setOnlineData_Promise(localDataObject).then(() => {
console.log("Data record #" + localDataObject['id'] + ": Online record created");
this.removeLocalData_Promise(localDataObject['id']).then(() => {
console.log("Data record #" + localDataObject['id'] + ": Local record removed");
}, (err) => {reject(err);});
}, (err) => {reject(err);});
});
resolve(true);
}, (err) => {reject(err);});
});
}
Given the asynchronous nature of promises, the above code generates the following console output:
- Data record #1: Online record created
- Data record #2: Online record created
- Data record #3: Online record created
- Data record #1: Local record removed
- Data record #2: Local record removed
- Data record #3: Local record removed
I understand why it does this (i.e. due to asynchronous nature), but is there any way I can get each promise to execute synchronously? I’ve tried using Promise.all
on the setOnlineData_Promise
and removeLocalData_Promise
promises and this results in getting them to execute in the correct order, however they still execute asynchronously.
Please help if you can!
Here is the code for my other functions FYI:
setData_Promise(storageKey,dataArray) {
return new Promise((resolve, reject) => {
this.storage.set(storageKey, dataArray).then(() => {
resolve(true);
}, (err) => {reject(err);});
});
}
getData_Promise(storageKey){
return new Promise((resolve, reject) => {
this.storage.get(storageKey).then((data) => {
if(data){
resolve(data);
} else {
reject(false);
}
}, (err) => {reject(err);});
});
}
setOnlineData_Promise(localDataObject){
//Retrieve & return online data
return new Promise((resolve, reject) => {
this.getData_Promise('online-db').then((onlineData: any) => {
if(onlineData){
//Push localDataObject onto online data
onlineData.push(localDataObject);
//Write onlineData to online data
this.setData_Promise('online-db',onlineData).then((result) => {
resolve(localDataObject);
}, (err) => {reject(err);});
//Return online data
resolve(onlineData);
} else {
//Write localDataObject to online data
this.setData_Promise('online-db',localDataObject).then((result) => {
resolve(localDataObject);
}, (err) => {reject(err);});
}
}, (err) => {reject(err);});
});
}
removeLocalData_Promise(localDataID){
return new Promise((resolve, reject) => {
this.getData_Promise('local-db').then((localData) => {
if(localData){
//Delete item from data set
localData = this.removeByKey_Function(localData, 'id', localDataID);
//Write returned data set to storage
this.setData_Promise('local-db',localData).then((result) => {
resolve(localData);
}, (err) => {reject(err);});
} else {
resolve(false);
}
});
});
}
removeByKey_Function(array, key, value) {
for (var i = 0; i < array.length; i++) {
if(array[i][key]==value){
array.splice(i,1);
break;
}
}
return array;
}