3

Below is a sample item object/record stored in DynamoDb. I use NodeJS and AWS.DynamoDB.DocumentClient to access the database.

I'm building out a PUT function to update the status for an JSON object in an array. The function will have access to the Item's uuid and room's uuid. How can I simply (creatively) update the value of corresponding status field, given the array of JSON objects?

Params:

let params = {
  TableName: room-table,
  Key: {
    uuid: event.body.uuid
  },
  UpdateExpression : "??",
  ExpressionAttributeNames: {
      "??":"??"
  },
  ExpressionAttributeValues:{
    "??":"??"
  },
  ReturnValues:"ALL_NEW"
};

Item Object:

{
  "Item": {
    "uuid": "77b1e88e-5e60-44d9-b6ca-aec345c0dc99",
    "rooms": [
      {
        "room": "303",
        "status": "pending",
        "uuid": "b8f1c1a8-04a9-4c2e-82ad-bc3e81face35"
      },
      {
        "room": "302",
        "status": "pending",
        "uuid": "42fdc61a-4a25-4316-90c9-60209875d208"
      },
      {
        "room": "678",
        "status": "pending",
        "uuid": "7bedc115-20ed-4c3e-9cd7-7fed0520f4df"
      }
    ],
    "status": "pending"
  }
}
2
  • 3
    It's not possible in a single update request because Dynamo will not be able to "find" the correct index in the Item.rooms array for you. The only way to make it possible would be for you to change Item.rooms from an array to an object where each key is a room's uuid. Then you could use an update expression of something like SET rooms.#roomUUID.status = :roomStatus. Commented Dec 6, 2016 at 16:07
  • Ok, can you submit that as your answer? Seems I'll need to use underscore jsto help me. Commented Dec 6, 2016 at 23:47

2 Answers 2

3

It's not possible to do this with ExpressionAttributeValues. I had to build a function to modify the object, similar to below:

function setStatus(jsonObj, uuid, newStatus) {
  for (var i=0; i<jsonObj.length; i++) {
    if (jsonObj[i].uuid === uuid) {
      jsonObj[i].status = newStatus;
      return jsonObj;
    }
  }
}
Sign up to request clarification or add additional context in comments.

Comments

-2
let params = {
  TableName: room-table,
  Key: {
    uuid: event.body.uuid
  },
  UpdateExpression : "SET #stat = :stat",
  ExpressionAttributeNames: {
      "#stat": "status"
  },
  ExpressionAttributeValues:{
    ":stat": "updatedStatusValue"
  },
  ReturnValues:"ALL_NEW"
};

ExpressionAttributeNames is needed because status is a DynamoDB reserved word. More info on Attribute Name and Attribute Value placeholders is available in the DynamoDB docs.

2 Comments

Just noticed that your question is about updating an entire array. My answer is about 1 element....
Hi Peter, my goal is to update a single object in the array, not the same field in all array objects.

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.