DynamoDB getItem returns empty item - node.js

I am using the aws-sdk within Node and trying to get an item from a DynamoDB table but it prints just Success {} and not the actual content of the item. Does anyone know how to get the actual content of the item?
The Node script I am using is the following:
// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'ap-southeast-2'});
// Create the DynamoDB service object
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var params = {
TableName: 'test_table',
Key: {
'TWEET_KEY' : {S: 'Test'}
},
ProjectionExpression: 'ATTRIBUTE_NAME'
};
// Call DynamoDB to read the item from the table
ddb.getItem(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data.Item);
}
});
and the actual data within the DynamoDB test_table which I'm trying to get is as follows:
Thank you very much!

Here - ProjectionExpression: 'ATTRIBUTE_NAME', you need to set the attribute names that you need to get, or just remove it to get the whole record content.

Related

AWS SAM and DynamoDB Local

I want to create a API endpoint in Node.js that lists the table names in DynamoDB. I have created a simple table locally and confirmed the table exists with the command
aws dynamodb list-tables --endpoint-url http://host.docker.internal:8000
{
"TableNames": [
"SampleTable"
]
}
but my lambda returns
{"TableNames":[]}
here's my lambda
const AWS = require('aws-sdk');
const options = {
apiVersion: '2012-08-10',
region: 'us-east-1',
};
if (process.env.AWS_SAM_LOCAL) {
options.endpoint = new AWS.Endpoint('http://host.docker.internal:8000');
}
const ddb = new AWS.DynamoDB(options);
exports.listTablesHandler = async (event) => {
if (event.httpMethod !== 'GET') {
throw new Error(`listTables only accept GET method, you tried: ${event.httpMethod}`);
}
console.info('received:', event);
const params = {};
let response = { statusCode: '500' };
try {
response = await ddb.listTables(params).promise();
} catch (err) {
console.log(err);
}
return response;
};
I expected the Lambda to list the name "SampleTable" in the API response
You should check if you are using -sharedDb ?
If you use the -sharedDb option, DynamoDB creates a single database file named shared-local-instance.db. Every program that connects to DynamoDB accesses this file. If you delete the file, you lose any data that you have stored in it.
If you omit -sharedDb, the database file is named myaccesskeyid_region.db, with the AWS access key ID and AWS Region as they appear in your application configuration. If you delete the file, you lose any data that you have stored in it.

Facing this error "ValidationException: The parameter cannot be converted to a numeric value: NaN"

I am trying to enter the data in AWS Dynamo DB through the AWS Lambda function using AWS HTTP API. FYI The data type of the parameter (Id) originally in Dynamo DB is Number but it is taking as String while parsing JSON data, so I have written "Number" beside "Id" parameter in order to convert it to "Number". When I am trying to run this lambda function I am getting this error. Please help, Thanks!
Lambda function:
payload: { "Id": $input.json('$.Id') "name": $input.json('$.name')
console.log('starting function');
const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region: 'us-east-1'});
exports.handler = function(event, ctx, callback) {
var params = {
Item: {
Id: Number(event.Id),
name: event.name
},
TableName: 'Test'
};
console.log(params)
docClient.put(params, function(err, data) {
if(err) {
callback(err, null);
} else{
callback(null, data);
}
});
}
Error log:
Look at the logs.
Your event.Id value is "NaN" which means "not a number".
Also event.name is "undefined".
So your problem is occuring here:
exports.handler = function(event, ctx, callback) {
Your event object is not populated with the values you are expecting.
The payload should be proper JSON and look something like:
{
"id": "6",
"name": "Test Name"
}
To achieve this, in your POST from your front-end code you could use something like:
data: JSON.stringify({"id": $('#Id').val(), "name": $('#name').val()})
Make sure that $('#Id').val() and $('#name').val() actually have proper values.

Trying to use AWS lambda to send data to a dynamodb table

console.log('starting function');
var dynamodb = new AWS.DynamoDB();
var AWS = require('aws-sdk');
exports.handler = function (e, ctx, callback) {
var params = {
Item: {
"Name": {
S: "Dalton Warden"
},
"PhoneNumber": {
S: "796-353-1416",
}
},
ReturnConsumedCapacity: "TOTAL",
TableName: "CustomerInfo"
};
dynamodb.putItem(params, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
};
I'm pretty new to lambda and dynamoDB but i'm trying to send data to a table I have set up. I've been through amazon's documentation and looked for similar instances on this site and The formatting looks like it would return the correct JSON but I'm still having trouble. The error I'm getting is Cannot read property 'DynamoDB' of undefined".
Please change the order of the below statements as mentioned below (first AWS and then dynamodb).
var AWS = require('aws-sdk');
var dynamodb = new AWS.DynamoDB();

Connect to DynamoDB in Node.JS

I am trying to get my Alexa skill programmed in Node.js to make a query in my dynamodb table.
I have this in the header:
var AWS = require("aws-sdk");
AWS.config.update({
region: "us-west-1",
});
var dynamodb = new AWS.DynamoDB();
var docClient = new AWS.DynamoDB.DocumentClient();
And in one of my intends I call this:
var params = {
TableName: 'TblName',
Key:{
"User": 'TestUser'
}
};
docClient.get(params, function(err, data) {
if (err) {
this.emit(':tell', 'A');
} else {
this.emit(':tell', 'B');
}
});
Now I thought that this would either throw an error, return A or return B. But for some reason, I simply get no response at all. Is there any obvious thing I am doing wrong?
Edit: If I change the table name to a non-existing one, I still don't get an error message or an A output. It just executes the rest of the code.
Edit: I guess one problem is identical to this one. I will close as soon as I got it fully working.

Get item from dynamodb table using separate index table with Node.js

I am creating a weather station using the Particle Electron and AWS. I have managed to get the returned data sent to a DynamoDB table "weather" which contains all of the weather data with the following schema (with included sample values):
Item{13}
deviceId: 540056000a51343334363138 (String) (Primary Partition Key)
tm: 1458754711 (Number) (Primary Sort Key)
batSoC: 89 (String)
batV: 4.01 (String)
hum: 27.9 (String)
lat: 41.2083 (String)
lon: -73.3439 (String)
pres: 968.4 (String)
temp: 19.8 (String)
uvI: 0.1 (String)
wDir: 0 (String)
wGst: 0.0 (String)
wSpd: 0.0 (String)
as well as a separate "weather_index" table which contains only the deviceId and tm attributes for the most recent data that was written to the main table (kind of like an atomic counter but for a periodically updated unix timestamp value). So if the "weather_index" item above was the most recent entry, the item in the "weather_index" table would look like this:
Item{2}
deviceIdString: 540056000a51343334363138 (String) (Primary Partition Key)
tmNumber: 1458754711 (Number)
I am currently trying to write a very basic web frontend in Node.js (which, prior to this project, I have had no experience with, so I am still learning) and can't figure out how to:
Perform a DynamoDB getItem which contains a parameter retrieved via a previous getItem. Like:
latestTime = getItem(weather_index, deviceId) // Gets the time "tm" of the most recent weather observation and stores it in "latestTime"
// Where "weather_index" is the table name
currentWeather = getItem(deviceId, tm) // Gets the weather observation for the specified "tm" value and stores it in "currentWeather"
// Where "tm" is the unix time-stamp of the most recent observation
I then want to be able to print the individual values to the terminal/webpage/carrier pigeon/etc... (Something along the lines of currentWeather.deviceId, currentWeather.tm, currentWeather.batSoC, etc...
I have the following code that I can't really make work properly:
/*
* Module dependencies
*/
var AWS = require('aws-sdk')
// weathermon_dev credentials
AWS.config.update({accessKeyId: 'REDACTED for obvious reasons', secretAccessKey: 'This bit too'});
// Select AWS region
AWS.config.update({region: 'us-east-1'});
var db = new AWS.DynamoDB();
// db.listTables(function(err,data) {
// console.log(data.TableNames);
// });
var time = Date.now() / 1000;
time = Math.round(time);
//console.log("Time: ");
//console.log(time);
time = Math.round(time);
var deviceId = "540056000a51343334363138"
var params = {
Key: {
deviceId: {S: deviceId}
},
TableName: 'weather_index'
};
var timeJson;
db.getItem(params, function(err,data) {
if (err) console.log(err); // an error occurred
else console.log(data); // successful response
var timeJson = JSON.parse(data);
})
// var timeJson = JSON.parse(data);
// var itemTime = timeJson.item;
console.log("timeJSON: " + timeJson);
// console.log("itemTime: " + itemTime);
var params = {
Key: {
deviceId: {S: deviceId},
time: {N: 'tm'}
},
TableName: 'weather'
};
db.getItem(params, function(err, data) {
if (err) console.log(err); // an error occurred
else console.log(data); // successful response
})
Any help would be greatly appreciated.
You need to look into how NodeJS asynchronous calls work. You would need to wait until the callback from the first getItem() is called before you perform the second getItem().
I've rewritten the relevant part of your code here, to show you what I'm talking about, but I recommend you try to understand why the code needs to be written in this way instead of just copy/pasting it.
var deviceId = "540056000a51343334363138"
var params = {
Key: {
deviceId: {S: deviceId}
},
TableName: 'weather_index'
};
var timeJson;
db.getItem(params, function(err,data) {
if (err) console.log(err); // an error occurred
else {
console.log(data); // successful response
var timeJson = JSON.parse(data);
console.log("timeJSON: " + timeJson);
// Inside this callback we have the weather_index tm value,
// so query the weather table here.
var params = {
Key: {
deviceId: {S: deviceId},
time: {N: 'tm'}
},
TableName: 'weather'
};
db.getItem(params, function(err, data) {
if (err) console.log(err); // an error occurred
else {
console.log(data); // successful response
// TODO: Use the database response data here
}
});
}
});

Resources