dynamodb node aws-sdk simple getItem() call - node.js

Folks, New to Javascript... trying to do simple dynamo queries from node:
var AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
var db = new AWS.DynamoDB();
var params = {
"TableName" : 'admins',
"Key" : [
{ "username" : { "S" : "foo" } },
],
}
db.getItem(params, function(err, data) {
console.log('error: '+ err);
console.log(data);
return next();
res.send(data);
});
}
Output:
error: UnexpectedParameter: Unexpected key 'username' found in params.Key['0']
Thanks! Any help would be greatly appreciated!

Must follow the SDK and Docs, its simple:
http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html
var params = {
AttributesToGet: [
"password"
],
TableName : 'foo',
Key : {
"username" : {
"S" : "bar"
}
}
}
db.getItem(params, function(err, data) {
if (err) {
console.log(err); // an error occurred
}
else {
console.log(data); // successful response
res.send(data);
}
return next();
});

I was trying to do it as it was suggested in the documentation, but also got errors.
At the end the following worked:
var aws = require('aws-sdk');
var db = new aws.DynamoDB({
region: 'eu-central-1',
maxRetries: 1
});
exports.handler = event => {
return queryMyThings();
}
const queryMyThings = async (event) => {
var params = {
Key: {
"ColumnByWhichYouSearch": {
S: "ValueThatYouAreQueriing"
}
},
TableName: "YourTableName"
};
return await db.getItem(params).promise();
}

Here are great resources for DynamoDB using NodeJS:
Getting Started guide
Documentaion and examples
If you're using the DocumentClient

Related

Data Item not getting inserted in DynamoDB Table from AWS Lambda Trigger

I have this Lambda code setup in JS for inserting a row in DynamoDB but the code seems to have some issue and doesn't trigger.Unable to figure out the issue as cloud watch also does captures anything. The API Gateway triggers the Lambda will inserts a row in DynamoDB. Tried debugging with console and logs also but unable to figure out the actual issue that is causing the code to break.
exports.handler = async (event) => {
console.log(event);
var eventBody = JSON.parse(event.body);
var eventType = eventBody.event_type;
var content = eventBody.content;
if (content.subscription) {
var subscription = content.subscription;
switch (eventType) {
case "subscription_created":
// Add new entry to License table
console.log('subscription created event');
var customer = content.customer;
var findUserScan = {
ExpressionAttributeValues: {
':email': { S: customer.email },
},
FilterExpression: 'email = :email',
TableName: _dynamodb_userprofile_table
};
try {
await dynamodb.scan(findUserScan, function (err, data) {
if (err) {
console.log("Error", err);
} else {
var userProfileAWS;
data.Items.forEach(function (userProfile, index, array) {
userProfileAWS = AWS.DynamoDB.Converter.unmarshall(userProfile);
});
var companyName;
if (userProfileAWS) {
companyName = userProfileAWS.organization;
}
try {
var licenseEntry = {
"subscriptionID": {
S: subscription.id
},
"companyName": {
S: companyName || ""
},
"customerEmail": {
S: customer.email
},
};
await dynamodb.putItem({
"TableName": _dynamodb_license_table,
"Item": licenseEntry
}).promise()
} catch (error) {
console.log(error)
throw new Error(`Error in dynamoDB: ${JSON.stringify(error)}`);
}
}
}).promise();
} catch (error) {
throw new Error(`Error in dynamoDB: ${JSON.stringify(error)}`);
}
break;

unable to get all items using query DynamoDB

How to scan all items from AWS dynamodb using node.js. I am posting my code here.
//Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
var unmarshalItem = require('dynamodb-marshaler').unmarshalItem;
// Set the region
AWS.config.update({region: 'us-east-1'});
// Create DynamoDB service object
var b = new AWS.DynamoDB({apiVersion: '2012-08-10'});
exports.handler = (event, context, callback) => {
var params = {
TableName: 'IoTdata2',
FilterExpression: "#deviceid = :unitID and #devicetimestamp BETWEEN :ftimestamp and :ttimestamp",
ExpressionAttributeNames: {
"#deviceid": "id",
"#devicetimestamp": "timestamp"
},
ExpressionAttributeValues: {
':unitID': {S: 'arena-MXHGMYzBBP5F6jztnLUdCL' },
':ftimestamp' : {S: '1584022680000' },
':ttimestamp' : {S: '1584023280000' }
},
};
b.scan(params, onScan);
function onScan(err, data) {
if (err) {
console.error("Unable to scan the table. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("Scan succeeded.");
var items = data.Items.map(function(val){
return unmarshalItem(val);
})
// continue scanning if we have more items
if (typeof data.LastEvaluatedKey != "undefined") {
console.log("Scanning for more...");
params.ExclusiveStartKey = data.LastEvaluatedKey;
b.scan(params, onScan);
}
}
callback(null, items);
}
};
I have followed the link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.NodeJs.04.html
I am getting time out here after a while. I have checked this link too
How to fetch/scan all items from `AWS dynamodb` using node.js
I am unable to return data properly i guess, Any suggestions ? Thanks
This worked for me by following Hank solution from here: How to fetch/scan all items from `AWS dynamodb` using node.js
exports.handler = async (event, context, callback) => {
let params = {
ExpressionAttributeNames: {
"#deviceid": "id",
"#devicetimestamp": "timestamp"
},
ExpressionAttributeValues: {
':unitID': {S: event.deviceid },
':ftimestamp' : {S: event.fromtime },
':ttimestamp' : {S: event.totime }
},
KeyConditionExpression: '#deviceid = :unitID and #devicetimestamp BETWEEN :ftimestamp and :ttimestamp',
TableName: 'IoTdata2'
};
let scanResults = [];
let items;
do {
items = await b.query(params).promise();
items.Items.map((item) => scanResults.push(unmarshalItem(item)));
params.ExclusiveStartKey = items.LastEvaluatedKey;
} while (typeof items.LastEvaluatedKey != "undefined");
var len = scanResults.length;
console.log(len);
callback(null, scanResults);
};

Lambda function unable to get data from dynamo DB for amazon lex - Null response

I am pretty new to node and facing a problem while trying to do a simple test on AWS lambda-dynamo DB integration in order to get a response for Amazon Lex request. If someone can say what needs to be changed that would be much appreciated. thanks..
Runtime - Node js 10.x and also tried on node js 8.10..
Below is the node JS sample code :
const AWS = require('aws-sdk');
var DBHandler = require("./DBHandler")
exports.handler = async (event) => {
console.log('This event is' +JSON.stringify(event))
var intent = event.currentIntent.name;
DBHandler.getalldetails(intent , function (err , data ) {
if (err) {
context.fail(err);
} else {
var response = {
"dialogAction": {
"type": "Close",
"fulfillmentState": "Fulfilled",
"message": {
"contentType": "PlainText",
"content": "data.Item.Message."
}
}
}
return response
//callback ( null, response );
}
});
};
Below is the ./DBHandler in another file under the same lamdba function folder.
const AWS = require('aws-sdk');
AWS.config.update({
region:"eu-west"
});
var docClient = new AWS.DynamoDB.DocumentClient();
var tableName = "testholly";
//exports.handler = (event,context,callback) => {
var getalldetails = (Intent,callback) => {
var params = {
TableName : tableName,
Key: {
"Intent":Intent
}
};
docClient.get(params,function (err,data) {
callback (err , data);
});
};module.exports = {
getalldetails
};
First check the Dynamo DB access permissions to that lambada. If at all not given, create a role to access the dynamoDB table and assign it to the lambda function.
If you want to access the dynamodb without role then use cognito pool ID or AWS access key Secret access key in AWS.config();
Sample:
AWS.config.update({
accessKeyId: "",
secretAccessKey: "",
region: "us-east-1"
});
OR
AWS.config.update({
"region":"us-east-1"
});
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId:"Your identity_pool_id"
});
your response is not within your callback from getAllDetails()....it should be. So something like:
exports.handler = async (event, context, callback) => {
console.log('This event is' + JSON.stringify(event))
var intent = event.currentIntent.name;
DBHandler.getalldetails(intent, function (err, data) {
if (err) {
context.fail(err);
} else {
var response = {
"dialogAction": {
"type": "Close",
"fulfillmentState": "Fulfilled",
"message": {
"contentType": "PlainText",
"content": data.Item.Message
}
}
}
callback(null, response)
}
});
};
You cannot use await w/ callbacks, you would need to "promisify" that bad boy. In the above, I pass the callback to the handler.

AWS cognito is giving serializationException(Start of structure or map found where not expected) while doing sign up in node.js How to fix this issue?

I'm trying to add signup functionality with AWS cognito, But While signing up up getting SerializationException How to resolve this issue?
My signup function look like this
const AmazonCognitoIdentity = require("amazon-cognito-identity-js");
const AWS = require("aws-sdk");
global.fetch = require("node-fetch");
const keys = require("../../config/keys");
AWS.config.update({
accessKeyId: keys.awsKeys.key,
secretAccessKey: keys.awsKeys.secret,
region: keys.region.awsRegionId
});
const poolConfig = {
UserPoolId: keys.cognito.userPoolId,
ClientId: keys.cognito.clientId
};
// create a new user pool
const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolConfig);
async function signupFunc(userData) {
console.log('JSON string received : ' + JSON.stringify(userData));
const emailData = {
Name: "email",
Value: userData.email
};
const name = {
Name: "name",
Value: userData.name
}
const password = userData.password;
const familyname = {
Name: 'family_name',
Value: userData.familyname
}
return new Promise((resolve, reject) => {
try {
var attributeList = [];
attributeList.push(new AmazonCognitoIdentity.CognitoUserAttribute(name));
attributeList.push(new AmazonCognitoIdentity.CognitoUserAttribute(familyname));
userPool.signUp(emailData, password, attributeList, null, (err, result) => {
if (err) {
console.error(`ERROR : ${JSON.stringify(err)}`);
return reject({ status: 0, error: "Error!!!" });
}
return resolve({
status: "200",
message: "Check email and verify!"
});
});
} catch (error) {
console.log(`ERROR : ${JSON.stringify(error)}`);
return reject({error: error});
}
});
}
module.exports = signupFunc;
While executing this method I'm getting below exception.
{
"code":"SerializationException",
"name":"SerializationException",
"message":"Start of structure or map found where not expected."
}
any help will much appreciated.
I had the same problem, because I was mistakenly passing the password as an Object instead of a String. Make sure you password is a String:
Auth.completeNewPassword(user, password, {} ).then(data=> console.log(data)})
Here user is an Object and password is a String.

Getting null value when trying to query value which is not present in dynamo db using node.js

I am new to dynamoDB and node.js I have written a code where it will make a query to the database (dynamodb) and look for an element which is entered by the user in the database. I am able to verify that but when the user tries with some other number which is not present in the database I am getting a null value.
My table name is "DevReferenceNumber" and only one column which is primary key "referencenumber".
'use strict';
var AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient({ region : 'us-east-1'});
function close(sessionAttributes, fulfillmentState, message) {
return {
sessionAttributes,
dialogAction: {
type: 'Close',
fulfillmentState,
message,
},
};
}
exports.handler = (event, context, callback) => {
try{
console.log(`event.bot.name=${event.bot.name}`);
if(event.bot.name != 'getCustomerReferenceNumber'){
callback('Invalid Bot Name');
}
dispatch(event, (response) => {
callback(null, response)
});
}catch(err){
callback("Error is occured while querying");
}
};
function dispatch(intentRequest, callback){
console.log(`dispatch UserID => ${intentRequest.userId}, intentName => ${intentRequest.currentIntent.name}`);
const intentName = intentRequest.currentIntent.name;
if(intentName === "checkReferenceNumber"){
return referenceNumber(intentRequest, callback);
}
}
function referenceNumber(intentRequest, callback){
const enteredReferenceNumber = intentRequest.currentIntent.slots.ReferenceNumber;
const sessionAttributes = intentRequest.sessionAttributes;
console.log("User has entered reference number is --> " + enteredReferenceNumber);
var params = {
TableName : "DevReferenceNumber",
KeyConditionExpression: "#refer = :ref",
ProjectionExpression : "#refer",
ExpressionAttributeNames: {
"#refer" : "referencenumber"
},
ExpressionAttributeValues:{
":ref": parseInt(enteredReferenceNumber)
}
};
docClient.query(params, function(err, data){
if(err){
callback(close(sessionAttributes, 'Fulfilled', {
contentType: 'PlainText',
content : 'Developer reference number is not matched with data from database'}));
}
else {
data.Items.forEach(function (item){
console.log("User matched data is ==> " + item.referencenumber);
callback(close(sessionAttributes, 'Fulfilled', {
contentType: 'PlainText',
content : 'Developer reference number is matched with data from database'}));
});
}
});
}
It is obvious that you will get a null record when you don't have a matching record. If you don't want null from node callback then you can do a custom logic to do a null check and return data according to the way you want.

Resources