I'm using DynamoDB to store data and trying to read items using JavaScript. I have a function that will read an item from a specified table, but I want to detect when an item doesn't exist in the table:
function getChapterLocations() {
var table = bibleSelect.value.replace(/\s/g, '');
var chapter = bookSelect.value + " " + chapterSelect.value;
var params = {
TableName: table,
Key:{
"chapter": chapter
}
};
var docClient = new AWS.DynamoDB.DocumentClient();
docClient.get(params, function(err, data) {
if (err) {
currentLocations = {};
} else {
currentLocations = data.Item.locations;
}
getText();
});
}
The problem is, even when an item doesn't exist in the table, err is always null. When an item doesn't exist, all I get is an error that looks something like this in the console:
callListeners https://sdk.amazonaws.com/js/aws-sdk-2.164.0.min.js:48:1027
emit https://sdk.amazonaws.com/js/aws-sdk-2.164.0.min.js:48:695 emitEvent
https://sdk.amazonaws.com/js/aws-sdk-2.164.0.min.js:47:18756
I would just ignore this error, but when an item doesn't exist, it prevents getText() from being called.
Related
On button click I have programmed to call a graphql api which is connected to a Lambda function and the function is pulling data from a dynamodb table. The query does not produce any error, but it doesn't give me any results as well. I have also checked the cloudwatch logs and I dont see any traces of the function being called. Not sure on the careless mistake I am making here.
Here is my api
void findUser() async {
try {
String graphQLDocument = '''query getUserById(\$userId: ID!) {
getUserById(userId: \$id) {
id
name
}
}''';
var operation = Amplify.API.query(
request: GraphQLRequest<String>(
document: graphQLDocument,
variables: {'id': 'USER-14160000000'}));
var response = await operation.response;
var data = response.data;
print('Query result: ' + data);
} on ApiException catch (e) {
print('Query failed: $e');
}
}
Here is my lambda function -
const getUserById = require('./user-queries/getUserById');
exports.handler = async (event) => {
var userId = event.arguments.userId;
var name = event.arguments.name;
var avatarUrl = event.arguments.avatarUrl;
//console.log('Received Event - ', JSON.stringify(event,3));
console.log(userId);
switch(event.info.fieldName) {
case "getUserById":
return getUserById(userId);
}
};
const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region: 'ca-central-1'});
async function getUserById(userId) {
const params = {
TableName:"Bol-Table",
KeyConditionExpression: 'pk = :hashKey and sk = :sortKey',
ExpressionAttributeValues: {
':hashKey': userId,
':sortKey': 'USER'
}
};
try {
const Item = await docClient.query(params).promise();
console.log(Item);
return {
id: Item.Items[0].pk,
name: Item.Items[0].details.displayName,
avatarUrl: Item.Items[0].details.avatarUrl,
createdAt: Item.Items[0].details.createdAt,
updatedAt: Item.Items[0].details.updatedAt
};
} catch(err) {
console.log("BOL Error: ", err);
}
}
module.exports = getUserById;
Upon button click I get this
Moving my comment to an answer:
Can you try changing your graphQLDocumnet to
String graphQLDocument = '''query getUserById(\$id: ID!) {
getUserById(userId: \$id) {
id
name
}
}''';
Your variable is $userId and then $id. Try calling it $id in both places like in your variables object.
Your flutter code is working fine but in lambda from the aws is returning blank string "" to not to print anything
I am trying to delete items in my Dynamodb table using Cloud Watch event triggered Lambda. This lambda scans the dynamo table and deletes all expired items. My code seems to be working when I test it using the test event in the console (i.e it deletes all the expired items). But when lambda gets triggered automatically using the Cloud Watch event it does not delete, event though I see that the lambda is being triggered.
exports.handler = async function () {
var params = {
TableName: TABLE_NAME
}
try {
const data = await docClient.scan(params).promise();
const items = data.Items;
if (items.length != 0) {
Promise.all(items.map(async (item) => {
const expirationDT = new Date(item.ExpiresAt);
const now = new Date();
if (now > expirationDT) {
console.log("Deleting item with otc: " + item.Otc + " and name: " + item.SecretName);
const deleteParams = {
TableName: TABLE_NAME,
Key: {
"Otc": item.Otc,
"SecretName": item.SecretName,
},
};
try {
await docClient.delete(deleteParams).promise();
} catch (err) {
console.log("The Secret was not deleted due to: ", err.message);
}
}
}))
}
} catch (err) {
console.log("The items were not able to be scanned due to : ", err.message)
}}
I know using DynamoDB TTL is an option, but I need these deletions to be somewhat precise, and TTL can sometimes take up to 48 hours, and I am aware I can use a filter when retrieving records to counter-act that. Just wondering what's wrong with my code here.
You need to await Promise.all or your lambda will end execution before it resolves
await Promise.all(items.map(async (item) => {
const expirationDT = new Date(item.ExpiresAt);
const now = new Date();
// ...
I want to update existing item of dynamoDB table using condition equivalent to like (%) condition of sql
opIdUserId status
123-U1 inprogress
345-U2 inprogress
123-U3 onhold
opIdUserId in my dynamodb is Primary partition key. I want to update status to COMP for opIdUserId field value starting from or contains 123.
this is what I am trying currently but researched and found I can not use KeyConditionExpression for update.
const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region: 'eu-west-1'});
var table = "tablename";
exports.handler = function(event, context, callback){
var params = {
TableName: table,
KeyConditionExpression: "begins_with(opIdUserId, :i)",
UpdateExpression: "set operationStatus = :o",
ExpressionAttributeValues:{
":o":"COMP",
":i":"123-"
},
ReturnValues:"UPDATED_NEW"
};
docClient.update(params, function(err, data) {
if (err) {
callback(err, null);
} else {
callback(null,data);
}
});
}
Please suggest how I can update my item in dynamoDB with specific condition.
You should create a Global Secondary Index on your table to query for the items that start with 123 using a KeyConditionExpression.
var params = {
TableName: table,
KeyConditionExpression: "id = :id AND begins_with(opIdUserId, :opIdUserId)",
UpdateExpression: "set operationStatus = :operationStatus",
ExpressionAttributeValues:{
":opIdUserId":"123-",
":id": "something"
}
};
var documentClient = new AWS.DynamoDB.DocumentClient();
documentClient.query(params, function(err, data) {
if (err) console.log(err);
else console.log(data);
});
Bare in mind that you can't run a query using BEGINS_WITH on a partition key, only on a sort key.
Then, you can use the update method over every individual element using the partition and sort key for the table, updating the operationStatus.
If you provide me with information regarding your DynamoDB table, I could help you create the GSI.
I am deleting a table in DynamoDB using the following Javascript in Node.
var params = {
TableName : "MyTable"
};
dynamodb.deleteTable(params, function(err, data) {
// Not really done yet...!
});
I need to know when the table has actually been deleted. The callback doesn't indicate this, as it is still in the deleting process when this is called. Is there a way to know when the delete has completed?
The waitFor API can be used to check for the non-existence of table.
Waits for the tableNotExists state by periodically calling the
underlying DynamoDB.describeTable() operation every 20 seconds (at
most 25 times).
Sample code to delete the table and check for the non-existence of table using waitFor API:-
var AWS = require("aws-sdk");
AWS.config.update({
region : "us-west-2",
endpoint : "http://localhost:8000"
});
var dynamodb = new AWS.DynamoDB();
var params = {
TableName : "country"
};
var paramsWaitFor = {
TableName : 'country' /* required */
};
function waitForTableNotExists() {
dynamodb.waitFor('tableNotExists', paramsWaitFor, function(waitForErr,
waitForData) {
if (waitForErr) {
console.log(waitForErr, waitForErr.stack); // an error occurred
} else {
console.log('Deleted ====>', JSON.stringify(waitForData, null, 2));
}
});
}
dynamodb.deleteTable(params, function(err, data) {
if (err) {
console.error("Unable to delete table. Error JSON:", JSON.stringify(
err, null, 2));
} else {
console.log("Deleted table. Table description JSON:", JSON.stringify(
data, null, 2));
waitForTableNotExists();
}
});
I'm using AWS Lambda and try to write something to AWS DynamoDB. I use the following code:
var tableName = "locations";
var item = {
deviceId: {
S: event.deviceId
},
timestamps: {
S: event.timestamp
}
}
var params = {
TableName: tableName,
Item: item
};
dynamo.putItem(params, function(err, data) {
if (err) {
context.fail(new Error('Error ' + err));
} else {
context.success(null);
}
});
And I get the following error:
returns Error ValidationException: One or more parameter values were invalid: Type mismatch for key deviceId expected: S actual: M
This happened because the aws sdk for Nodejs had changed!
If you are using:
var doc = require('dynamodb-doc');
var dynamo = new doc.DynamoDB();
Then the parameters to the putItem call (and most other calls) have changed and instead needs to be:
var tableName = "locations";
var item = {
deviceId: event.deviceId,
timestamp: event.timestamp,
latitude: Number(event.latitude),
longitude: Number(event.longitude)
}
var params = {
TableName: tableName,
Item: item
};
Read all about the new sdk here: https://github.com/awslabs/dynamodb-document-js-sdk