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' }
}
CodePudding user response:
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;
CodePudding user response:
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();