Search code examples
node.jsasynchronousasync-awaitamazon-dynamodbaws-sdk-nodejs

Assign Async function returned value to a variable in Node.JS


I have a function below that grabs data from DynamoDB and then returns true or false upon evaluation of a condition. This function will be used to do a simple check and determine the elevation of the user for data access and whatnot.

How can I get this function to do something like:

var auth = aliasHasRole('foo','bar')
console.log(auth) // prints value passed down by aliasHasRole().

I figured I had to declare it as async and added await before returning but no luck, then did aliashHasRole('foo','bar').then( (x) => { auth = x}), but it returns undefined.


Here's the full code:

var AWS = require('aws-sdk');
AWS.config.update({
    region: 'us-west-2',
    accessKeyId: "xxx",
    secretAccessKey: "xxx",
});
const docClient = new AWS.DynamoDB.DocumentClient();


function aliasHasRole(an_alias, a_role) {
    const params = {
        TableName: 'xxx',
        KeyConditionExpression: '#alias= :alias AND #Role= :Role',
        ExpressionAttributeNames: {
            '#alias': 'alias',
            '#Role': 'Role'
        },
        ExpressionAttributeValues: {
            ':alias': an_alias,
            ':Role': a_role,
        }
    };

    docClient.query(params).promise()
        .then(
            (data) => {
                //this line below returns true or false, how can I get I pass this value so I can return it from the aliasHasRole as true or false?
                console.log(data.Items.length > 0 && data.Items[0].alias === an_alias && data.Items[0].Role === a_role ? true : false);
                return data.Items.length > 0 && data.Items[0].alias === an_alias && data.Items[0].Role === a_role ? true : false;
            })
        .catch((err) => {
            console.log(err)
        })
};

var auth;
aliasHasRole("xxx","TeamManager");//should return true or false just like it logs it to the console.
//Do something to assign functions value to var auth.
console.log(auth) //print value passed by function...

//How can I assign this value to a variable? as in var auth = aliasHasTole('foo','bar') // auth is now true or false.

Solution

  • You are not using the async/await keyword right.Modify your function like this and try.

    var AWS = require('aws-sdk');
    AWS.config.update({
        region: 'us-west-2',
        accessKeyId: "xxx",
        secretAccessKey: "xxx",
    });
    const docClient = new AWS.DynamoDB.DocumentClient();
    
    // you can use async and await like this
    let aliasHasRole = async function (an_alias, a_role) {
    
        try {
            const params = {
                TableName: 'xxx',
                KeyConditionExpression: '#alias= :alias AND #Role= :Role',
                ExpressionAttributeNames: {
                    '#alias': 'alias',
                    '#Role': 'Role'
                },
                ExpressionAttributeValues: {
                    ':alias': an_alias,
                    ':Role': a_role,
                }
            };
    
            // this will resolve the value 
            let data = await docClient.query(params).promise()
            return data.Items.length > 0 && data.Items[0].alias === an_alias && data.Items[0].Role === a_role ? true : false;
        }
        catch (err) {
            //this is equivalent .catch statement
            console.log(err)
        }
    };
    // This has to be self executing function in case of async await
    (async () => {
        var auth = await aliasHasRole("xxx", "TeamManager");
        // This will print the value of auth which will be passed from the aliasHasRole ie. True or False
        console.log(auth) //print value passed by function aliasHasRole...
    })()
    
    

    You can also use this without async/await

    
    var AWS = require('aws-sdk');
    AWS.config.update({
        region: 'us-west-2',
        accessKeyId: "xxx",
        secretAccessKey: "xxx",
    });
    const docClient = new AWS.DynamoDB.DocumentClient();
    
    // you can use async and await like this
    function aliasHasRole(an_alias, a_role) {
    
        const params = {
            TableName: 'xxx',
            KeyConditionExpression: '#alias= :alias AND #Role= :Role',
            ExpressionAttributeNames: {
                '#alias': 'alias',
                '#Role': 'Role'
            },
            ExpressionAttributeValues: {
                ':alias': an_alias,
                ':Role': a_role,
            }
        };
    
        // Return is the main part. The error was that you are not using the return key word with Promise that's why it was not working
        return docClient
            .query(params)
            .promise()
            .then(data => data.Items.length > 0 && data.Items[0].alias === an_alias && data.Items[0].Role === a_role ? true : false)
            .catch(error => {
                // You can handle the error here
                console.log(error)
            })
    };
    
    
    aliasHasRole("xxx", "TeamManager").then(auth => {
        // This will print the value of auth which will be passed from the aliasHasRole ie. True or False
        //print value passed by function...
        console.log(auth)
    })