user3872094
user3872094

Reputation: 3351

Confused with promises in a loop

I'm writing a dynamodb code that does the below.

  1. Scan a particular column and get the values and add it to an array
  2. convert the array to set and back to array to get the unique values
  3. Loop through this set values as a parameter and get the actual value.

Basically trying to create a group by in DynamoDb.

Here the 1st and 2nd step I'm able to do it. but coming to step 3 I've a loop and inside the loop the code has to be executed and my code is as below.

var AWS = require("aws-sdk");
var creds = new AWS.Credentials('akid', 'secret', 'session');

AWS.config.update({
    "accessKeyId": "myAccessId",
    "secretAccessKey": "MySecretAccessKey",
    "region": "us-east-1"
});

var dynamodb = new AWS.DynamoDB.DocumentClient();

var params = {
    TableName: "MyTable",
    FilterExpression: "#target_state = :target_state",
    ExpressionAttributeNames: {
        "#target_state": "target_state"
    },
    ExpressionAttributeValues: {
        ":target_state": "5"
    }
};
var array = [];


dynamodb.scan(params).promise().then(function (data) {
    data.Items.forEach(function (itemData) {
        array.push(itemData.ruleNo)
    });
    console.log(array);
    return array;
}).then(() => {
    console.log("Entered 2nd block " + [...new Set(array)]);
    var array2 = [...new Set(array)];

    for (index = 0; index < array2.length; ++index) {
        console.log(array2[index]);
        var params1 = {
            TableName: "ChemicalData",
            FilterExpression: "#target_state = :target_state and #ruleNo=:ruleNo",
            ExpressionAttributeNames: {
                "#target_state": "target_state",
                "#ruleNo": "ruleNo"
            },
            ExpressionAttributeValues: {
                ":target_state": "5",
                ":ruleNo": array2[index]
            }
        };


return dynamodb.scan(params1).promise().then(function (data) {
            var uw = JSON.stringify((data.Items));
            return uw;
        });
    }
}).then((data) => {
    console.log(data);
}).catch(err => {
    console.log(err)
})

when I run this program, the result that I get is only one value, and that is the first array value, I'm unable to know on how can I loop through all the array variables and then do a console.log(data). please let me know on where am I going wrong and how can I fix this.

Thanks

Upvotes: 0

Views: 966

Answers (1)

ponury-kostek
ponury-kostek

Reputation: 8060

Using return inside for breaks the loop. You should gather promises from inner scan into array and use Promise.all to resolve then together

dynamodb.scan(params).promise().then(function (data) {
    data.Items.forEach(function (itemData) {
        array.push(itemData.ruleNo)
    });
    console.log(array);
    return array;
}).then(() => {
    console.log("Entered 2nd block " + [...new Set(array)]);
    var array2 = [...new Set(array)];
    var results = []; //results array
    for (index = 0; index < array2.length; ++index) {
        console.log(array2[index]);
        var params1 = {
            TableName: "ChemicalData",
            FilterExpression: "#target_state = :target_state and #ruleNo=:ruleNo",
            ExpressionAttributeNames: {
                "#target_state": "target_state",
                "#ruleNo": "ruleNo"
            },
            ExpressionAttributeValues: {
                ":target_state": "5",
                ":ruleNo": array2[index]
            }
        };

        // push results to be resolved later
        results.push(dynamodb.scan(params1).promise().then(function (data) {
            var uw = JSON.stringify((data.Items));
            return uw;
        }));
    }
    // return promise that resolves when all results resolve
    return Promise.all(results);
})

Upvotes: 1

Related Questions