I am new to all this so apologies in advance. I am trying to query a Dynamodb using nodejs and lambda so I can get Alexa to return the value. The dynamodb table is set up to look something like:
date time filmname
2018-01-04 13:00 Titanic
2018-01-04 15:30 Titanic
2018-01-04 18:30 Paddingtion
2018-01-05 12:00 Star Wars
My table is setup with the: Primary partition key = date (String) Primary sort key = time (String)
Now what I want to do is query or get the information from dynamodb for a particular date so for 2018-01-04 3 items should return. Is this possible using nodejs within Lambda and allow alexa to read back all the items?
I have already setup the following code within my intent and this works fine:
var params = {
TableName: 'Cinema',
Key:{ "date": "2018-01-04", "time" : "13:00" }
};
docClient.get(params, (err, data) => {
if (err) {
this.emit(':tell', 'Test Error');
} else {
this.emit(':tell', 'Test Working ' + data.Item.title);
}
});
The above code returns Titanic, as expected. However, I am stuck as to how to get it to return all the items for a given date rather than just for that particular time.
I am able to run this js code standalone (i.e not in lambda) and this works fine. Although I suspect this is not the best way of doing it.
var params = {
TableName: 'Cinema',
KeyConditionExpression: "#date = :yymmdd and #time between :time1 and :time2",
ExpressionAttributeNames:{
"#date": "date",
"#time": "time"
},
ExpressionAttributeValues: {
":yymmdd":"2018-01-04",
":time1":'0',
":time2":'2'
}
};
docClient.query(params, function(err, data) {
if (err) {
console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
} else {
console.log("Query succeeded.");
data.Items.forEach(function(item) {
console.log(" -", item.title + ": ");
});
}
});
Now if I run this code within Lambda and try and test the skill I get 'The remote endpoint could not be called, or the response it returned was invalid.' Also, for some reason my cloudwatch logs are not updating for that particular lambda function so I am unable to get further information for it at this time.
If anyone is interested, I solved the problem. It was as simple as ensuring that the response that is sent to Alexa was only triggered once.
I am new to this so although the code works as required I am open to any suggestions on best practice.
function queryDynamoDate_single() {
const startdate = this.attributes['startdate'];
var say = '';
var params = {
TableName: 'Cinema',
KeyConditionExpression: "#date = :yymmdd and #time between :time1 and :time2",
ExpressionAttributeNames:{
"#date": "date",
"#time": "time"
},
ExpressionAttributeValues: {
":yymmdd":startdate,
":time1":'0',
":time2":'2'
}
};
readDynamoItem(params, myResult=>{
say = myResult;
say = 'you asked,. The answer is: ' + myResult;
this.response.speak(say).listen('try again');
this.emit(':responseReady');
});
}
.
function readDynamoItem(params, callback) {
var title = [];
var time = [];
var noofitems = 0;
let speechOutput = "";
docClient.query(params, (err, data) => {
if (err) {
this.emit(':tell', 'Test Error');
} else {
console.log("Query succeeded.");
data.Items.forEach(function(item) {
console.log(" -", item.title + ": ");
noofitems = noofitems + 1;
title[noofitems] = item.title;
time[noofitems] = item.time;
});
for (var l = 1; l <= noofitems ; l++){
{
speechOutput = speechOutput + title[l];
}
callback(speechOutput);
}
});
}