0

I am working with Amazon DynamoDB and Express.

I need to render a view based on the data from a Amazon DynamoDB table.

My code works fine when I work with callback API instead of trying to use promise.

But I want to use promise because to keep my code clean, otherwise I need to call res.send() from inside the callback of the docClient.scan(params).

My code for working with promise as follows I can't figure out what is wrong;

async function test(params){
    AWS.config.loadFromPath('./awsconfigtest.json');
    let docClient = new AWS.DynamoDB.DocumentClient();
    await docClient.scan(params).promise();
}

Below is the content of the route file;

/* GET home page. */
router.get('/', function(req, res, next) {

    let scanResults ;
    let params = {
        TableName: 'dummy'
    };

    test(params).then((data,err)=>{
        console.log(data,err);
        data.Items.forEach(function (element, index, array) {
            scanResults.push({name: element.name, nodeId: element.nodeId});
            console.log(element.name + " (" + typeof element.nodeId + ")");
        });
    });

    console.log(scanResults);
    res.render("index",{nodes:scanResults});    
});

3 Answers 3

3

Main reason is your test function does not get back anything - You forgot return keyword.

But, I think the best practice is don't mix async/await syntax with Promise solve syntax (.then .catch).

This is way use async/await:

async function test(params){
    AWS.config.loadFromPath('./awsconfigtest.json');
    let docClient = new AWS.DynamoDB.DocumentClient();
    return await docClient.scan(params).promise(); // !!! You forgot return keyword
}
/* GET home page. */
router.get('/', async function (req, res, next) { // async function
  try {
    let scanResults;
    let params = {
      TableName: 'dummy'
    };

    const data = await test(params); // await for `data`
    console.log(data);

    data.Items.forEach(function (element, index, array) {
      scanResults.push({ name: element.name, nodeId: element.nodeId });
      console.log(element.name + " (" + typeof element.nodeId + ")");
    });

    console.log(scanResults);
    res.render("index", { nodes: scanResults });

  } catch (err) {
    res.status(500).send(err); // handle exception
  }
});
Sign up to request clarification or add additional context in comments.

Comments

0

I believe you could use promisify from node util.

Something like this:

const util = require('util');

async function test(params){
    AWS.config.loadFromPath('./awsconfigtest.json');
    let docClient = new AWS.DynamoDB.DocumentClient();
    const scan = util.promisify(docClient.scan);
    await scan(params);
}

The promisify function converts a function that takes a callback as its last value, and converts it into a promise, that will reject the err value, and resolve the data value (from something like docClient.scan(params, (err, data) => {}))

Comments

0
 try {
    const params = {TableName : NOTES_TABLE_NAME};
    const notes = await util.promisify((cb) => documentClient.scan(params, cb))();
    cb(null, send(200, notes));
  }
  catch (err){
    cb(null, send(500, err.message));
  }

Worked for me.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.