4

I want to use new nodejs 8.10 for developing my lambdas. A simple piece of code when written in node 6.10 style works but the same(similar) code doesn't work when I use node 8.10.

Below is working code which successfully inserts data into dynamodb table(nodejs 6.10)

var AWS = require('aws-sdk');
// Set the region 
AWS.config.update({region: 'us-east-1'});
var documentClient = new AWS.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});


exports.handler = (event, context, callback) => {
    // TODO implement

    var params = {
      Item: {
        client: 'client_'+Math.random(),
        Type: 1,
        Status: true,
        json: { foo: 'bar', address:{ city:'Pune', street: 'ABC Nagar', pin:'411099'} }
      },
      TableName: 'clients'
    };

    documentClient.put(params, function(err, data) {
      if (err) {
        console.log("Error", err);
        callback(err, null);
      } else {
        console.log("Success", data);
        // return "Hi, insert data completed";
        callback(null, data);
      }
    });
};

And below one which is node 8.10 style which doesn't work(means doesn't insert data into dynamodb table). I keep getting null as return value.

var AWS = require('aws-sdk');
// Set the region 
AWS.config.update({region: 'us-east-1'});
var documentClient = new AWS.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});


exports.handler = async (event) => {
    // TODO implement

    var params = {
      Item: {
        client: 'client_'+Math.random(),
        Type: 1,
        Status: true,
        json: { foo: 'bar', address:{ city:'Pune', street: 'ABC Nagar', pin:'411099'} }
      },
      TableName: 'clients'
    };

    documentClient.put(params, function(err, data) {
      if (err) {
        console.log("Error", err);
      } else {
        console.log("Success", data);
        return "Hi, insert data completed";
      }
    });
};

I spent searching 2-3 hours searching.. couldn't find any article or any question similar. Can anyone tell me what am I doing wrong?

3 Answers 3

10

Async / Await is a syntactical sugar for promise, Your documentClient.put should be wraped with promise. Since documentClient.put is based on callback appoach, you have to wrap it with promise

var AWS = require('aws-sdk');
// Set the region 
AWS.config.update({region: 'us-east-1'});
var documentClient = new AWS.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});

exports.handler = async (event) => {
    // TODO implement

    var params = {
      Item: {
        client: 'client_'+Math.random(),
        Type: 1,
        Status: true,
        json: { foo: 'bar', address:{ city:'Pune', street: 'ABC Nagar', pin:'411099'} }
      },
      TableName: 'clients'
    };

    let putItem = new Promise((res, rej) => {
        documentClient.put(params, function(err, data) {
          if (err) {
            console.log("Error", err);
            rej(err);
          } else {
            console.log("Success", data);
            res("Hi, insert data completed");
          }
        }); 
    });

    const result = await putItem;
    console.log(result);    
    return result
};

Note: Its advisable to use DB operations in separate file,rather than using in handler function itself

Sign up to request clarification or add additional context in comments.

2 Comments

Worked for me. I guess we can make putItem more reusable by making it a function(params). What do you say?... anyway Thanks.
Its good to go. Even try creating new class called DBHelper.js and place all your common functions for putItem, getItem and so on. Make sure that you have wrapped your all your aws functions are wrapped with Promise.
6

Did you look in your table to see if it's inserting data? I think it is.

The problem with your async-style code is that you aren't returning a value. Returning "Hi, insert data completed" from the put callback doesn't return a value from handler.

You could manually create a promise and return that from handler, but I'd try using promisify.

This code is untested but should be close:

...
const util = require('util');
...
documentClient.putPromise = util.promisify(documentClient.put);
...
try {
    const data = await documentClient.putPromise(params);
    console.log("Success", data);
    return "Hi, insert data completed";
}
catch (err) {
    console.log("Error", err);
}

Here's more on promisify: http://2ality.com/2017/05/util-promisify.html

5 Comments

Yey, got it work. thanks. its just that we have to add the new put/putPromise in the same documentClient object... it will be like documentClient.putPromise = util.promisify(documentClient.put); ... then we have to call putPromise on documentClient object .... like... const data = await documentClient.putPromise(params);... if you can please modify your answer.
@MahammadJilanBasha thank you for following up! I updated my answer.
'exports.handler = async (event) => { // TODO implement var params = { ........ }; documentClient.putPromise = util.promisify(documentClient.put); try { const data = await documentClient.putPromise(params); console.log("Success", data); return "Hi, insert data completed"; } catch (error) { console.log("Error", err); } }; '
@MahammadJilanBasha Ignore last comment. Couldn't delete for some reason. Do I just replace the 'documentClient.put' with the 'try' and 'catch' part ?
@Rashik, Yes you need to try-catch part in place of 'documentClient.put'. Also please note that we need to add 'putPromise' to documentClient object before we can use it.
3

Calling await dynamo.put(params).promise(); is how I solved this issue after some googling. Specifically, it seems like calling foo.promise(); in the aws sdk is supported now.

1 Comment

Yup, the Request object returned by dynamo.put() now has a .promise() method that returns a promise, so this works on pretty much anything that returns a Request.

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.