1

I'm attempting to migrate my v2 Lambdas to v3, and I'm having some trouble incrementing a value. Here's my v2 method:

  const params = {
    TableName: process.env.USER_TABLE_NAME!,
    Key: { UID },
    UpdateExpression: 'SET #numRatings = #numRatings + :increment',
    ExpressionAttributeNames: {
      '#numRatings': 'numRatings'
    },
    ExpressionAttributeValues: {
      ':increment': 1
    },
    ReturnValues: 'ALL_NEW'
  };

  return await DB.update(params).promise();

v3 method:

  const params = {
    TableName: process.env.USER_TABLE_NAME!,
    Key: {
      UID
    },
    UpdateExpression: 'set numRatings = numRatings + :increment',
    ExpressionAttributeValues: {
      ':increment': 1
    },
    ReturnValues: 'ALL_NEW'
  } as unknown as UpdateItemCommandInput;

  try {
    const response = await dbClient.send(new UpdateItemCommand(params));
    console.log('response', response);
  } catch (error) {
    console.error('error', error);
  }

I'm using TypeScript and VS Code gives this error:

Types of property 'Key' are incompatible.
    Type '{ UID: string; }' is not comparable to type '{ [key: string]: AttributeValue; }'.
      Property 'UID' is incompatible with index signature.
        Type 'string' is not comparable to type 'AttributeValue'

CloudWatch gives this unhelpful error:

Cannot read property '0' of undefined

I'm really confused as, as far as I can tell I have followed the documentation properly, their equivalent of "params" is defined as so:

export const params = {
  TableName: "TABLE_NAME",
  Key: {
    primaryKey: "VALUE_1", // For example, 'Season': 2.
    sortKey: "VALUE_2", // For example,  'Episode': 1; (only required if table has sort key).
  },
  // Define expressions for the new or updated attributes
  UpdateExpression: "set ATTRIBUTE_NAME_1 = :t, ATTRIBUTE_NAME_2 = :s", // For example, "'set Title = :t, Subtitle = :s'"
  ExpressionAttributeValues: {
    ":t": "NEW_ATTRIBUTE_VALUE_1", // For example ':t' : 'NEW_TITLE'
    ":s": "NEW_ATTRIBUTE_VALUE_2", // For example ':s' : 'NEW_SUBTITLE'
  },
  ReturnValues: "ALL_NEW"
};

My apologies if that's too many code examples but I wanted to be thorough. UID is a string. Thank you in advance for any help

4
  • Why aren't you giving the partition key name? Commented Jan 20, 2022 at 21:26
  • Have you pinned down specifically which line is producing the error you described (just to rule out that it's not some external issue)? Commented Jan 21, 2022 at 0:14
  • @hunterhacker, the partition key is “UID”, ES6 allows for the key and value to be shortened to just the name of both if they’re the same alligator.io/js/object-property-shorthand-es6 Commented Jan 21, 2022 at 10:02
  • 1
    @Norman the track in AWS doesn’t refer to a specific line, but the only line it could possibly be is “const response = await dbClient.send(new UpdateItemCommand(params));” Commented Jan 21, 2022 at 10:03

1 Answer 1

2

Keys and ExpressionAttributeValues need their Dynamo type defined as so:

...
  Key: {
    UID: { S: UID }
  },
...
  ExpressionAttributeValues: {
    ':val': { N: '1' }
  },
Sign up to request clarification or add additional context in comments.

2 Comments

Right. Notice how in this Key block there's both a name and a value for the partition key? In your sample there's just a value, no name. You may be thinking "Well the database knows the partition key name and there's no sort key so a simple value should work!" but you still need to specify it as a name-value pair.
Was battling prettier / ESLint to stop it from removing it but even “UID: UID” wasn’t working. The AWS SDK documentation should be updated to reference the requirement for the key type

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.