How to reformat DynamoDB response from nodejs client - node.js

When I make a get request from dynamoDB using the aws nodejs client the result contains a response with the type as the Key i.e.
{
Item: {
newrelic_id: {
S: 'nr-1234'
}
,
jumpcloud_id: {
S: 'j-234'
}
,
microtime: {
N: '1475690490854'
}
,
instance_id: {
S: 'i-abc1234'
}
}
}
Note that the keys to the values are the prefixes for the types , S for String and N for Number is there a way to remove this "type key"?

Here is the sample code using DocumentClient.
var AWS = require("aws-sdk");
var creds = new AWS.Credentials('akid', 'secret', 'session');
AWS.config.update({
region : "us-west-2",
endpoint : "http://localhost:8000",
credentials : creds
});
var docClient = new AWS.DynamoDB.DocumentClient();
var table = "Movies";
var year_val = 2015;
var title = "The Big New Movie";
var params = {
TableName : table,
KeyConditionExpression : 'yearkey = :hkey and title = :rkey',
ExpressionAttributeValues : {
':hkey' : year_val,
':rkey' : title
}
};
docClient.query(params, function(err, data) {
if (err) {
console.error("Unable to read item. Error JSON:", JSON.stringify(err,
null, 2));
} else {
console.log("GetItem succeeded:", JSON.stringify(data, null, 2));
}
});
Output:-
The output doesn't have the data type of the attribute.
GetItem succeeded: {
"Items": [
{
"title": "The Big New Movie",
"yearkey": 2015,
"info": {
"rating": 0,
"plot": "Nothing happens at all."
}
}
],
"Count": 1,
"ScannedCount": 1
}

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;

AWS Lambda update function showing ValidationException

I am trying to update data by lamda function. I just created a PUT Method and add lambda function in method after reading documentation i created a function here is the code
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB({region: 'us-east-2', apiVersion: '2012-08-10'});
AWS.config.update({region: 'us-east-2', apiVersion: '2012-08-10'});
var docClient = new AWS.DynamoDB.DocumentClient();
exports.handler = (event, context, callback) => {
const params = {
TableName: "Would-You-Rather",
Key:{
"QuestionID": "a670b861-8a34-4bda-93e0-8bbf2cd25eb6",
},
UpdateExpression: "set would = :w, rather = :r, wouldClick = :wC, , ratherClick = :rC ",
ExpressionAttributeValues:{
":w": "Working",
":r": "Working",
":wC": 12,
":rC": 1
},
ReturnValues:"UPDATED_NEW"
};
console.log("Updating the item...");
docClient.update(params, function(err, data) {
if (err) {
console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2));
}
});
};
But when I am testing the function it's showing
"message": "Invalid UpdateExpression: Syntax error; token: \",\", near: \", , ratherClick\"",
"code": "ValidationException",
If i wrap ExpressionAttributes like this
ExpressionAttributeValues:{
":w": "Working",
":r": "Working",
":wC": "12",
":rC": "1"
},
Then its showing this error
"errorType": "Runtime.UserCodeSyntaxError",
"errorMessage": "SyntaxError: Invalid or unexpected token",
This is my POST method which is working fine add this because maybe it will help in better understanding
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB({region: 'us-east-2', apiVersion: '2012-08-10'});
exports.handler = (event, context, callback) => {
const params = {
Item: {
"QuestionID": {
S: context.awsRequestId
},
"Would": {
S: event.would
},
"Rather": {
S: event.rather
},
"wouldClick": {
N: event.wouldClick
},
"ratherClick": {
N: event.ratherClick
}
},
TableName: "Would-You-Rather"
};
dynamodb.putItem(params, function(err, data) {
if (err) {
console.log(err);
callback(err);
} else {
console.log(data);
callback(null, data);
}
});
};
Codepen code
var xhr = new XMLHttpRequest();
xhr.open('PUT', 'https://iv9803zj9d.execute-api.us-east-2.amazonaws.com/Development/would-you-rather');
xhr.onreadystatechange = function(event) {
console.log(event.target.response);
}
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'allow');
xhr.send(JSON.stringify({Would: Coffe, Rather: Tea, wouldClick: 15, ratherClick: 13, QuestionID: 3e8976be-e763-4c69-84c3-be03ec4a38de}));
There's a syntax error. You forgot to put the closing quote here
"QuestionID": "a670b861-8a34-4bda-93e0-8bbf2cd25eb6",

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);
};

How to scan in dynamoDB based on the values in an array?

here is my code where i have a list of values in an array. I need to fetch all the projects from project table which matches the id's in the array.
var arr=[];
for(var index in data.Items){
if(data.Items[index].hasOwnProperty('projectId'))
arr.push(data.Items[index].projectId);
};
var params = {
TableName: 'projects',
FilterExpression: 'id IN (:id)',
ExpressionAttributeValues: {
':id': arr
}
};
dynamodbclient.scan(params, function (err, docs) {
if (err) {
console.log("Error", err);
} else {
console.log("Success");
callback(err, docs.Items);
}
});
However i am not getting the proper results.
Option 1 - Static :-
If you know all the values its count upfront, please construct the FilterExpression as mentioned below:-
var params = {
TableName : "projects",
FilterExpression : "id IN (:id1, :id2)",
ExpressionAttributeValues : {
":id1" : "id val 1",
":id2" : "id val 2"
}
};
Option 2 - Dynamic:-
var titleValues = ["The Big New Movie 2012", "The Big New Movie"];
var titleObject = {};
var index = 0;
titleValues.forEach(function(value) {
index++;
var titleKey = ":titlevalue"+index;
titleObject[titleKey.toString()] = value;
});
var params = {
TableName : "Movies",
FilterExpression : "title IN ("+Object.keys(titleObject).toString()+ ")",
ExpressionAttributeValues : titleObject
};
docClient.scan(params, onScan);
function onScan(err, data) {
if (err) {
console.error("Unable to scan the table. Error JSON:", JSON.stringify(
err, null, 2));
} else {
// print all the movies
console.log("Scan succeeded.");
data.Items.forEach(function(movie) {
console.log("Item :", JSON.stringify(movie));
});
// continue scanning if we have more movies
if (typeof data.LastEvaluatedKey != "undefined") {
console.log("Scanning for more...");
params.ExclusiveStartKey = data.LastEvaluatedKey;
docClient.scan(params, onScan);
}
}
}

Confused on querying DynamoDB

I've the below data in my DynamoDB.
and I'm trying to achieve the below result.
scan through the table and get the rows where the management is NULL and Location is Midwest.
I initially tried the below query to match the Null.
var scanningParameters = {
TableName: 'LOB',
FilterExpression: "#mgmt contains NULL",
ExpressionAttributeNames: {
"#mgmt": "Management",
}
};
docClient.scan(scanningParameters, onScan);
function onScan(err, data) {
if (err) {
console.error("Unable to scan the table. Error JSON:", JSON.stringify(err, null, 2));
} else {
// print all the movies
console.log("Scan succeeded.");
data.Items.forEach(function (data) {
console.log(
data.lineofbusiness + " name : ",
data.name);
});
if (typeof data.LastEvaluatedKey != "undefined") {
console.log("Scanning for more...");
scanningParameters.ExclusiveStartKey = data.LastEvaluatedKey;
docClient.scan(scanningParameters, onScan);
}
}
}
I get the exception as
{
"message": "Invalid FilterExpression: Syntax error; token: \"contains\", near: \"#mgmtcontains NULL\"",
"code": "ValidationException",
"time": "2017-05-03T13:21:11.611Z",
"requestId": "0T0GU59HRJ24P96D42H9QNC97RVV4KQNSO5AEMVJF66Q9ASUAAJG",
"statusCode": 400,
"retryable": false,
"retryDelay": 13.73953651636839
}
please let me know where am I going wrong and how can I fix this.
Here is the scan item for "NULL" value (i.e. String attribute having NULL as data).
I assume that Management attribute is of String data type containing the string value "NULL".
Code:-
var AWS = require("aws-sdk");
var creds = new AWS.Credentials('akid', 'secret', 'session');
AWS.config.update({
region: "us-west-2",
endpoint: "http://localhost:8000",
credentials : creds
});
var docClient = new AWS.DynamoDB.DocumentClient();
var params = {
TableName: "lob",
FilterExpression: "#mgmt = :mgmtVal",
ExpressionAttributeNames: {
"#mgmt": "Management",
},
ExpressionAttributeValues : {
":mgmtVal" : "NULL"
}
};
docClient.scan(params, onScan);
var count = 0;
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.");
data.Items.forEach(function(itemData) {
console.log("Item :", ++count,JSON.stringify(itemData));
});
if (typeof data.LastEvaluatedKey != "undefined") {
params.ExclusiveStartKey = data.LastEvaluatedKey;
docClient.scan(params, onScan);
}
}
}

Resources