1
votes

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.

1
You have an extra closing brace after console.log('Get item succeeded', data); not sure how it runs without error though.Richard Dunn
I had omitted some of the code above where the ... isJames Gaudet

1 Answers

1
votes

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);
    }
});