i have an function that runs inside my cloudcode that uses batches to deepsave all the data i need to save. Inside this cloudcode is this function
async function deepSaveProduct(batches) {
var stepIds = [];
var featureIds = [];
for (let step of product.steps) {
if (step.objectId !== undefined) {
stepIds.push(step.objectId);
}
for (let feature of step.features) {
if (feature.objectId !== undefined) {
featureIds.push(feature.objectId);
}
}
}
var stepStore = Backendless.Data;
for (const stepId of stepIds) {
Backendless.Data.of("Steps")
.setRelation(
{
objectId: stepId,
},
"features",
[]
)
.then( function(obj) {
console.log("then is working");
if (stepId === stepIds[stepIds.length - 1]) {
console.log("last step");
}
})
.catch(function (error) {
console.error(error);
});
}
for (const featureId of featureIds) {
Backendless.Data.of("features")
.setRelation(
{
objectId: featureId,
},
"subspecs",
[]
)
.then(function (featureRequest) {
if (featureId === featureIds[featureIds.length - 1]) {
console.log("last feature");
}
})
.catch(function (error) {
console.error(error);
});
}
for (const batch of batches) {
Backendless.Data.of("Products").deepSave(batch);
}
}
the problem im having is that i want to first delete the the relations and then add them with deepsave so that my relations are updated. This should happen after the last relation is deleted but because the code runs async sometimes the data gets deepsaved before the relations are deleted, which end up in deleting all my relations. The .then function are not working how do i solve this
Each of Backendless SDK method calls return Promise instance on which you can wait for method call to complete. In your case execution order matters so you should “chain” all the calls together using awaitJS keyword. Just place before methods calls which should be executed first this keyword and logic will start to work as expected.
hi @Andriy_Konoz thanks for your response, i chained them together and put the await keyword in the code but when i tested it it wont finish the first setRelation function in the loop. I dont get any errors ``` // STEP 1: create arrays of stepIds and featureIds
idBuilder();
function idBuilder() {
var stepIds = [];
var featureIds = [];
console.log("STEP 1: create arrays of stepIds and featureIds");
for (let step of product.steps) {
if (step.objectId !== undefined) {
stepIds.push(step.objectId);
}
for (let feature of step.features) {
if (feature.objectId !== undefined) {
featureIds.push(feature.objectId);
}
}
}
removeStepRelation(stepIds, featureIds);
}
// STEP 2: remove the relations of the steps
async function removeStepRelation(stepIds, featureIds) {
console.log("STEP 2: remove the relations of the steps");
console.log(stepIds.length, "STEPS TOTAL");
for (const stepId of stepIds) {
await Backendless.Data.of("steps")
.setRelation(
{
objectId: stepId,
},
"features",
[]
)
.then(function (result) {
return result;
});
if (stepId === stepIds[stepIds.length - 1]) {
removeFeatureRelation(featureIds);
}
}
}
// STEP 3: remove the relations of the features
async function removeFeatureRelation(featureIds) {
console.log("STEP 3: remove the relations of the features");
for (const featureId of featureIds) {
await Backendless.Data.of("features")
.setRelation(
{
objectId: featureId,
},
"subspecs",
[]
)
.then((obj) => {
if (featureId === featureIds[featureIds.length - 1]) {
deepSaveProduct(batchClean(batches));
}
return obj;
})
.catch(function (error) {
console.error(error);
});
}
}
// STEP 4: deep save the batches
async function deepSaveProduct(batches) {
console.log("STEP 4: deep save the batches");
for (const batch of batches) {
Backendless.Data.of("Products").deepSave(batch);
}
}```
@Andriy_Konoz sure i handle a lot of data but when i console.log after the first await nothing is happening. The code just infinitely awaits without throwing timeout errors in the RT logs the id is : 49B7E3B6-7054-A807-FF2A-A5C9AAA52D00
its also weird because i had it first running clientside but due to saving time and possible data loss i moved it to an cloud function and now something isnt adding up anymore
2023-09-27 11:33:54,283 | SERVER_CODE | INFO | [59011] Building ServerCode Model for path (/opt/backendless/repo/49b7e3b6-7054-a807-ff2a-a5c9aaa52d00/files/servercode/JS/default/PRODUCTION)
2023-09-27 11:33:54,287 | SERVER_CODE | INFO | [59011] ServerCode Model built in 9ms
2023-09-27 11:33:54,289 | SERVER_CODE | INFO | [59011] [2c5ad670-f40f-44af-b6ed-53cf5ef65719] [INVOKE HANDLER] custom.deepSave (async)
2023-09-27 11:33:54,300 | SERVER_CODE | INFO | [59011] STEP 1: create arrays of stepIds and featureIds
2023-09-27 11:33:54,300 | SERVER_CODE | INFO | [59011] STEP 2: remove the relations of the steps
2023-09-27 11:33:54,300 | SERVER_CODE | INFO | [59011] 4 STEPS TOTAL
2023-09-27 11:33:54,300 | SERVER_CODE | INFO | [59011] FB455065-C489-44B6-8E92-359A9572FBA1
2023-09-27 11:33:54,354 | SERVER_CODE | INFO | [59011] Processing finished in 203.810ms
Time is in UTC. It looks like first 2 steps are executed and calls ends after that
yes ive seen it, it stops right after the first api call it just stops working without any timeout errors. So it stops at the first time i use the setRelation API call. i tried logging the response in the .then part but that doesnt execute
@mark-piller hi, i dont know where your comment went but i have put the await before every setRelation and it looks like its timing out but it doesnt time out
This logic will not work with a more significant amount of data. So when you face the issue with invocation timeout - try to rework it using Promise.all for places where a group of requests could be run in parallel.