ConditionalCheckFailedException: Update nested attributes in DynamoDb table — JavaScript SDK

Jorge Freitas
2 min readApr 29, 2021
Photo by Campaign Creators on Unsplash

Problem: Update query with nested attributed. I was receiving ConditionalCheckFailedException when the nested attribute was null.

After some research I figure out a workaround to be able to set nested attributes even if the root attribute is null.

Before

const updateParams: DocumentClient.UpdateItemInput = {
TableName: tableName,
Key: { keyName },
ConditionExpression: "#storeNumber = :storeNumber",
UpdateExpression: “SET #storeStatus.#status = :newStoreStatus, #storeStatus.#updatedOn = :newStatusUpdatedOn”,
ExpressionAttributeNames: {
"#storeNumber": "storeNumber",
"#storeStatus": "storeStatus",
"#status": "status",
"#updatedOn": "updatedOn",
},
ExpressionAttributeValues: {
":storeNumber": storeNumber,
":newStoreStatus": "online",
":newStatusUpdatedOn": "2021-04-29T13:29:00.9360188+00:00",
},
},
};

After

const updateParams: DocumentClient.UpdateItemInput = {
TableName: tableName,
Key: { keyName },
ConditionExpression: "#storeNumber = :storeNumber",
UpdateExpression: "SET #storeStatus = :newStoreStatus",
ReturnValues: "UPDATED_NEW",
ExpressionAttributeNames: {
"#storeNumber": "storeNumber",
"#storeStatus": "storeStatus",
},
ExpressionAttributeValues: {
":storeNumber": storeNumber,
":newStoreStatus": { status: "online", updatedOn: "2021-04-29T13:29:00.9360188+00:00" },
},
};
  • ConditionExpression: is the condition to find the row to update;
  • UpdateExpression: here you set your query. In this case I am using the alias #storeStatus = :newStoreStatus (the value, is set in ExpressionAttributeValues);
  • ExpressionAttributeNames: you set the alias (the name used in query) = column name from dynamo;
  • ExpressionAttributeValues: here you set the values to use in this query.

Where is the magic?

The magic here is in UpdateExpression instead of set each nested attribute, you set the entire object. This way even when the storeStatus is null this still work.

Scenarios where this strategy works:

Nested attribute: storeStatus

  • storeStatus correctly filled
{
"storeNumber": "0123456789",
"storeStatus": {
"status": "online",
"updatedOn": "2021-04-29T13:29:00.9360188+00:00"
}
}
  • storeStatus is null
{
"storeNumber": "0123456789",
"storeStatus": null
}
  • storeStatus is empty
{
"storeNumber": "0123456789",
"storeStatus": {
}
}

I hope this helps someone 🍀

--

--