vinod827
vinod827

Reputation: 1524

Unable to update the item in DynamoDB using the GSI

I have the following structure in my dynamodb table:- id: partition_key user_id: GSI

Following is my Lambda where I'm trying to get the value of user_id from the client in the user object (in JSON) and then trying to update the Dynamodb item using the query operation but it is not working:-

exports.lambdaHandler = async (event, context) => {
  logger.info('event:', event);
  let body, data;
  let statusCode = 200;
  const headers = {
    'Content-Type': 'application/json',
    'Access-Control-Allow-Headers': 'Content-Type',
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': '*'
  };
  const user = JSON.parse(event.body).user;
  const updatedOn = new Date().getTime();
  try {
    const params = {
      TableName: ddbTable,
      IndexName: 'user_id-index',
      KeyConditionExpression: 'user_id = :id',
      ExpressionAttributeValues: {
        ':id': user.id
      }
    };

    dynamodb.query(params, function (err, result) {
      console.log("result", result);
      data = result;
      if (err) {
        console.log("Unable to query item. Error JSON:", JSON.stringify(err));
      } else {
        const parameters = {
          TableName: ddbTable,
          Key: {
            "id": result.Items[0].id
          },
          UpdateExpression: "set first_name = :f, last_name = :l, postal_code = :p, country_code = :c, updated_on = :u",
          ExpressionAttributeValues: {
            ":f": user.firstName,
            ":l": user.lastName,
            ":p": user.postalCode,
            ":c": user.countryCode,
            ":u": updatedOn
          },
          ReturnValues: "UPDATED_NEW"
        };
        dynamodb.update(parameters, function (err, data) {
          if (err) console.log(err);
          else console.log(data);
        });
      }
    });
    console.log("*********");
  } catch (err) {
    console.log(err);
    statusCode = 400;
    body = err.message;
    return err;
  } finally {
    body = JSON.stringify(data);
  }
  return {
    statusCode,
    body,
    headers
  };
};

The query operation is not working at all. This statement is not getting executed

dynamodb.query(params, function (err, result) {

Please suggest.

Upvotes: 0

Views: 147

Answers (1)

fedonev
fedonev

Reputation: 25639

There are two patterns to invoke asynchronous calls such as dynamodb.query in a Node.js Lambda handlers: async-await or callbacks. Because your handler implements neither correctly, the Lambda returns without the SDK calls finishing.

The recommended approach is async-await. Add the await keyword and promisify the method with .promise(). This pattern is preferred because it removes the "callback hell" of nested SDK calls.

const queryResult = await dynamodb.query(params).promise()

const updateParams = {
  Key: { "id": queryResult.Items[0].id },
  ...
}

const updateResult = await dynamodb.update(updateParams).promise()

For callback pattern examples, see the above link or this from the awsdocs repo.

Note: AWS SDK for JavaScript v3 is now stable and the recommended version.

Upvotes: 1

Related Questions