'How to do update in AWS Dynamo DB using NodeJS

I have written this function to do update in dynamo table

const updateTask = async (req, res) => {
  try {
    const { existingTaskText,updatedTaskText } = req.body;
    console.log(existingTaskText,updatedTaskText );
    UPDATE({
      TableName: "todos",
      Key:{ task: existingTaskText},
      UpdateExpression:"set task = :task",
      ExpressionAttributeValues: {":task": updatedTaskText},
    });
    res.status(200).json({ data: "this is controller" });
  } catch (error) {
    res.status(400).json({ message: error.message });
  }
};

this is calling UPDATE

const UPDATE = async (payload) => {
  try {
    console.log(payload);
    const updateDoc = await dbClient
      .update({
        TableName: payload.TableName,
        Key: payload.Key,
        UpdateExpression: payload.UpdateExpression,
        ExpressionAttributeNames:payload.ExpressionAttributeNames,
        ReturnValues: "UPDATED_NEW",
      })
      .promise();
    console.log(updateDoc);
  } catch (error) {
    console.log(error);
  }
};

When I am testing this in postman, I am getting this error

ValidationException: Invalid UpdateExpression: An expression attribute value used in expression is not defined; attribute value: :task

this is payload log getting passed

{
  TableName: 'todos',
  Key: { task: 'see its  done' },
  UpdateExpression: 'set task = :task',
  ExpressionAttributeValues: { ':task': 'edited' }
}


Solution 1:[1]

I made below common functions for the update, get, and create a table.use the same.

const AWS = require('aws-sdk');
AWS.config.update({ region: "us-east-1",accessKeyId : process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY });
const dynamoDB = new AWS.DynamoDB()
const documentClient = new AWS.DynamoDB.DocumentClient();

const Dynamo = {
    async get(id, TableName) {
        const params = {
            TableName,
            Key: {
                id,
            },
        };

        const data = await documentClient.get(params).promise();

        if (!data || !data.Item) {
           throw Error(`There was an error fetching the data for ID of ${id} from ${TableName}`);
           
        }
        console.log(data);

        return data.Item;
    },
    async getall(TableName) {
        const params = {
            TableName: TableName,
          };

        const data = await documentClient.scan(params).promise();

        if (!data || !data.Item) {
            throw Error(`There was an error fetching the data for ID of ${ID} from ${TableName}`);
        }
        console.log(data);

        return data.Items;
    },
    async getMany(params) {
        const data = await documentClient.scan(params).promise();
        console.log(data);
        if (!data || !data.Items) {
            throw Error(`There was an error fetching the data`);
        }

        return data.Items;
    },

    async write(data, TableName) {
        console.log('write dynamo',data, TableName);
        if (!data.id) {
            throw Error('no ID on the data');
        }

        const params = {
            TableName,
            Item: data,
        };

        const res = await documentClient.put(params).promise();

        if (!res) {
            throw Error(`There was an error inserting ID of ${data.id} in table ${TableName}`);
        }
        console.log('res of write dynamo ',res);
        return data;
    },
    async createTable(TableName) {
    documentClient
    .scan({
            TableName: TableName,
        })
    .promise()
    .catch(error => {
  
        return new Promise(resolve => {
            dynamoDB
            .createTable({
              AttributeDefinitions: [
                {
                  AttributeName: "id",
                  AttributeType: "S",
                },
              ],
              KeySchema: [
                {
                  AttributeName: "id",
                  KeyType: "HASH",
                },
              ],
              BillingMode: "PAY_PER_REQUEST",
              TableName: TableName,
            })
            .promise()
            .then(data => console.log("Success!", data))
            .catch(console.error)
        })
      });

    },

};
module.exports = Dynamo;

Solution 2:[2]

When you call the dbClient.update method, you are declaring the parameter ExpressionAttributeNames. It should be ExpressionAttributeValues. This is why the error message indicates that expression attribute value used in expression is not defined.

So you can try it changing the dbClient.update call in this way:

const updateDoc = await dbClient
  .update({
    TableName: payload.TableName,
    Key: payload.Key,
    UpdateExpression: payload.UpdateExpression,
    ExpressionAttributeValues:payload.ExpressionAttributeValues,
    ReturnValues: "UPDATED_NEW",
  })
  .promise();

Solution 3:[3]

Here as you are setting 'ExpressionAttributeNames:', you have to set 'ExpressionAttributeValues' as well.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Viral Patel
Solution 2 OARP
Solution 3 Oshidi