Multiple api requests not working in business logic

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

Hi @Joppe_Derks ,

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 await JS keyword. Just place before methods calls which should be executed first this keyword and logic will start to work as expected.

Regards, Andriy

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);
        }
    }```

@Joppe_Derks ,

Maybe you try to handle a lot of data during one call and execution time exceeds max execution time. Have you checked application logs?

Could you please provide your app ID?

Regards, Andriy

@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

when you last time ran this code?

the working one clientside monday and the bad cloud function couple of minutes ago

In logs of you app I see next entries

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

Could you add await before:

  • using deepSaveProduct function
  • using removeFeatureRelation function
  • using removeStepRelation function

And make idBuilder async and it call with await.

If it is possible - run that request on a little bunch of data.

In general, it looks to me like we don’t wait for the execution of all processes with relations.

thanks alot Dima its working :+1:

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.