Search code examples
javascriptangularpromiseamazon-dynamodbaws-sdk-js

I am trying to use promise ina function to receive data and put them in array and then return the array


My function uses promises, but it is not working correctly:

getShirtcolorsCount(){
    var params_red ;
    var red ;
    var params_blue ;
    var blue ;
    var numb = 0 ;
    var docClient = new DynamoDB.DocumentClient();

    // Query voor Shirts 
    params_red = {
        TableName: 'ShirtApp',
        IndexName: 'Shirt-index',
        KeyConditionExpression: 'ShirtC = :sbs AND ShirtQuantity >  :snr ' ,
        ExpressionAttributeValues: {
            ':sbs': 'Red' ,
            ':snr' : numb
        }
    };

    var redPromise = docClient.query(params_red).promise();
    redPromise.then(function(data){
        console.log('Success');  
        red = data.Count;
    }).catch(function(err) {
        console.log(err);
    });

    params_blue = {
        TableName: 'ShirtApp',
        IndexName: 'Shirt-index',
        KeyConditionExpression: 'ShirtC = :sbs AND ShirtQuantity >  :snr ' ,
        ExpressionAttributeValues: {
            ':sbs': 'Blue' ,
            ':snr' : numb
        }
    };

    var bluePromise = docClient.query(params_blue).promise();
    bluePromise.then(function(data){
        console.log('Success');  
        blue = data.Count ;      //NEED THAT to add to the array
    }).catch(function(err) {
        console.log(err);
    });

    var ShirtInfo = [{
        name: 'RedColor',
        value: red
    }, {
        name: 'BlueColor',
        value: blue
    }];

    // **** HERE I NEED HELP what should I PUT in the Promise.all for the array
    // I want redPromise and bluePromise to run at the same time after I receive 
    // data then add then to the array and return the array as the function
    Promise.all([redPromise, bluePromise]).then([ShirtInfo])

    return ShirtInfo;
}

As I added in comments, I want to run redPromise and BluePromise at the same time and after they received data from the web, add them to the array. And after that return that array. Almost everything works only the part where Promise.all is used. I can't figure out what to put after .then so the values would be added to the array:

Promise.all([redPromise, bluePromise]).then([])

And I can't figure out what to put to return the array using promise.


Solution

  • Some issues:

    • You need to return the value of red and blue inside the then callback, otherwise those promises will resolve to undefined.
    • Likewise, you need to return the return value of Promise.all
    • You cannot acccess red and blue synchronously, as those will still be undefined. So that must happen within a then callback.

    I would also avoid the code duplication you have, and work with a list of colors you are interested in, and then cycle through those:

    getShirtcolorsCount(){
        var params;
        var colors;
        var promises;
        var numb = 0;
        var docClient = new DynamoDB.DocumentClient();
    
        colors = ['Red', 'Blue']; // <--- make code generic
        promises = colors.map(function (color) {
            // Query voor Shirts 
            var param = {
                TableName: 'ShirtApp',
                IndexName: 'Shirt-index',
                KeyConditionExpression: 'ShirtC = :sbs AND ShirtQuantity > :snr ',
                ExpressionAttributeValues: {
                    ':sbs': color, // <-- make it dynamic to avoid code duplication
                    ':snr' : numb
                }
            };
            return docClient.query(params_red).promise();
        });
    
        // Make sure to return the promise    
        return Promise.all(promises).then(function (responses) {
            console.log('Success');  
            var shirtInfo = responses.map(function (data, i) {
                return {
                    name: color[i] + 'Color',
                    value: data.Count
                };
            });
            return shirtInfo;
        }).catch(function(err) {
            console.log(err);
        });
    }
    

    Once you work with promises, you must use the results as promises too. You cannot expect a function to return the value synchronously. So when you call getShirtcolorsCount, use then to access the result:

    getShirtcolorsCount().then(function (shirtInfo) {
        console.log(shirtInfo);
    });