1

I'm working on a lambda function that will store information about different users. I have an atribute, userID as my primary partition key, and storedObject as my primary sort key. When I use PutItem, I want it to only add the item if it doesn't already exist in the storedObject attribute.

This is my code

    var params = {
        TableName: 'TrackItDB',
        Item: {
          'userID' : {S: currentUser},
          'storedObject' : {S: itemName},
          'lenderPerson' : {S: personName},
          'objectStatus' : {S: 'lent'},
          'transactionDate': {S: date},
        }
      };
....
const checkIfItemIsStoredParams = {
        Key: {
        "userID" : {
            S: currentUser
        },
        "storedObject" : {
            S: itemName
        }
    },
        TableName: "TrackItDB"
    };
.....
  dynamodb.getItem(checkIfItemIsStoredParams, function(err, data) {

        if (!data) { 
            // no match, add the item
            console.log('Item did not exist, storing to DB');
            console.log(params);
            return dynamodb.putItem(params, function(err, data) {
                if (err) {
                    console.log("Error", err);
                } else {
                    console.log("Success", data);
                }
               });
        }       
        else {
          console.log('Get item succeeded', data);   
              }
        } 
        });

The problem I'm having is that it always outputs Get Item succeeded to the console even if there is no data. I've tried both if (data) and if (!data) and both return the get item succeeded even when there is no data returned.

2
  • You have an extra closing brace after console.log('Get item succeeded', data); not sure how it runs without error though. Commented Nov 2, 2018 at 1:17
  • I had omitted some of the code above where the ... is Commented Nov 2, 2018 at 17:21

1 Answer 1

1

getItem returns an array even if it doesn't find the item you're looking for. Therefore, your conditional statement will always be truthy since you're checking for whether data is null/undefined. You should instead check for the length of data:

if (!data.length) { // item doesn't exit
    // put new item
}

An alternative solution would be to simplify what you're trying to do by making a single call to DynamoDB instead of two. This might be a good idea if you're worried about performance or AWS usage costs. putItem has the parameter ConditionExpression which allows you to have fine-grain control over which items should be updated based on conditions that you specify.

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html

For your case it might look something like this:

var params = {
    TableName: 'TrackItDB',
    Item: {
      'userID' : {S: currentUser},
      'storedObject' : {S: itemName},
      'lenderPerson' : {S: personName},
      'objectStatus' : {S: 'lent'},
      'transactionDate': {S: date},
    },
    ConditionExpression: 'attribute_not_exists(storedObject)'
};

dynamodb.putItem(params, function(err, data) {
    if (err) {
        console.log("Error", err);
    } else {
        console.log("Success", data);
    }
});
Sign up to request clarification or add additional context in comments.

1 Comment

The 'if (!data.length)' did not work, but that's OK the conditionExpression does and as you stated is the much better way to do. Thank you for your help.

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.