I have the following code I am trying to upload to DynamoDB local host using Node.js.
Is there a possible work around. For the following error?
Unable to add event undefined . Error JSON: {
"message": "One of the required keys was not given a value",
"code": "ValidationException",
"time": "2016-06-28T04:02:26.250Z",
"requestId": "970984e4-3546-41f0-95f9-6f1b7167c510",
"statusCode": 400,
"retryable": false,
"retryDelay": 0
}
Here is the code. I would like the Item: {} to accept whatever values may be present, and add them to the table.
var AWS = require("aws-sdk");
var fs = require('fs');
AWS.config.update({
region: "us-west-2",
endpoint: "http://localhost:8000"
});
var docClient = new AWS.DynamoDB.DocumentClient();
console.log("Importing movies into DynamoDB. Please wait.");
var allMovies = JSON.parse(fs.readFileSync('moviedata.json', 'utf8'));
allMovies.forEach(function(movie) {
var params = {
TableName: "Movies",
Item: {
"year": movie.year,
"title": movie.title,
"info": movie.info,
"twitter": movie.twitter
}
};
docClient.put(params, function(err, data) {
if (err) {
console.error("Unable to add movie", movie.title, ". Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("PutItem succeeded:", movie.title);
}
});
});
As you are looping over a promise call, you need a safeguard that the current promise resolves before you begin the next.
var AWS = require("aws-sdk");
var fs = require('fs');
const tableName = 'Movies';
AWS.config.update({
region: "local",
endpoint: "http://localhost:8000"
});
var docClient = new AWS.DynamoDB.DocumentClient();
console.log("Importing movies into DynamoDB. Please wait.");
var allMovies = JSON.parse(fs.readFileSync('moviedata.json', 'utf8'));
for (let i = 0, p = Promise.resolve(); i < allMovies.length; i++) {
p = p.then(_ => new Promise(resolve =>
setTimeout(function () {
var params = {
TableName: tableName,
Item: {
"year": allMovies[i].year,
"title": allMovies[i].title,
"info": allMovies[i].info
}
};
docClient.put(params, function(err, data) {
if (err) {
console.error("Unable to add movie", allMovies[i].title, ". Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("PutItem succeeded:", allMovies[i].title);
}
});
resolve();
}, 10)
));
}
Related
I have the following Lambda function to delete an item from my DynamoDB.
const AWS = require("aws-sdk");
AWS.config.update({ region: "us-west-2" });
var docClient = new AWS.DynamoDB.DocumentClient();
var deleteContact = function(event,callback) {
var params = {
TableName:"Contacts",
Key:{
id: event.id
},
ConditionExpression: "set event.id = :id",
ExpressionAttributeValues: {
":id": event.id
}
};
console.log("Attempting a conditional delete...");
docClient.delete(params, function(err, data) {
if (err) {
console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
}
});
};
deleteContact();
and here is the code in my react app which is requesting:
export const removeContact = createAsyncThunk(
'contactsApp/contacts/removeContact',
async (contactId, { dispatch, getState }) => {
await axios.post('https://API.amazonaws.com/prod', {
key1: `${contactId}`
});
console.log(contactId)
return contactId;
}
);
Currently, code works and deletes the parameters in the row. But the problem is it will not remove the id from the DynamoDB table. So everything will be deleted EXCEPT id.
As result, I would have GHOST items in my DynamoDB table:
DynamoDB screenshot
I have a lambda function that's suppose to be writing to a database. When I run it on my local machine it works but then when I upload it to lambda and test it It doesn't put anything in the database. The role I have the function using has full access to DynamoDB and its the exact same code that works fine when I run it from my laptop. Any idea why that would be the case?
Here's my lambda. The dao class contains the code that actually accesses dynamo. I'm just trying to upload some constant strings right now.
const DAO = require('./PostStatusDAO.js');
exports.handler = async (event, context, callback) => {
var dao = new DAO();
dao.post("this is a test", "#jordan", "#matt", "none");
const response = {
statusCode: 200,
body: {
result: "good"
}
};
return response;
};
const AWS = require('aws-sdk');
const ddb = new AWS.DynamoDB.DocumentClient({region: 'us-west-2'});
class PostStatusDAO {
post(in_text, in_user, in_author, in_attachment) {
var params = {
Item: {
user: String(in_user),
timestamp: Date.now(),
author: String(in_author),
text: String(in_text),
attachment: String(in_attachment),
},
TableName: 'Feed',
};
console.log(params);
var result = ddb.put(params, (err, data) => {
console.log("callback");
if(err) {
console.log("Error: ", err);
} else {
console.log("Data: ", data);
}
});
// console.log(result);
}
}
module.exports = PostStatusDAO;
To see the reason why your function is failing you have to either run it synchronously or return the promise back to the caller/runtime like this:
const DAO = require('./PostStatusDAO.js');
exports.handler = async(event, context, callback) => {
var dao = new DAO();
// Return new promise
return new Promise(function(resolve, reject) {
// Do async job
dao.post("this is a test", "#jordan", "#matt", "none", function(err, data) {
if (err) {
console.log("Error: ", err);
reject(err);
}
else {
console.log("Data: ", data);
resolve(data);
}
})
})
};
const AWS = require('aws-sdk');
const ddb = new AWS.DynamoDB.DocumentClient({region: 'us-west-2'});
class PostStatusDAO {
async post(in_text, in_user, in_author, in_attachment, callback) {
var params = {
Item: {
user: String(in_user),
timestamp: Date.now(),
author: String(in_author),
text: String(in_text),
attachment: String(in_attachment),
},
TableName: 'Feed',
};
console.log(params);
return ddb.put(params, callback).promise();
}
}
module.exports = PostStatusDAO;
I'm trying to update 3 nested items in a db table,my lambda runs fine and doesnt give any erros,but when a query the table it doesnt show the new values,i´m not sure if im invoking the table or passing the arguments correctly
my partion key/primary key is badgeNumber
my dynamoDB table looks like this:
(the items i'm trying to update are date,hour,register to yyy-mm-dd,hh-mm-ss and true
{
"assistance": [
{
"date": "null",
"hour": "null",
"register": false
}
],
"badgeNumber": "0000",
"data": {
"cardType": "elem",
"firstName": "Moriuks",
"imageURL": "url",
"lastName": "Mora",
"position": "Student"
}
}
the condition to update the items is if register is = false then write the new values to the table.
my code looks like this
pppp
var updateAsisstance = function(day,hour,id){
var docClient = new AWS.DynamoDB.DocumentClient();
var params = {
TableName:"someTable",
Key: { badgeNumber : 0000 },
UpdateExpression: "SET #asi[0].#reg = :locVal",
ExpressionAttributeNames: {
'#asi': 'asisstance',
'#reg': 'register',
},
ConditionExpression: "NE(#asi[0].#reg:true)",
ExpressionAttributeValues:{
":date":day,
":hour":hour,
":locVal":true
},
ReturnValues:"UPDATED_NEW"
};
docClient.update(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data);
}
});
};
after defining the funcion,im calling it using
updateAssistance(day,hour,id)
the expected output should look something like this:
"assistance": [
{
"date": "yyyy-MM-DD",
"hour": "HH-MM-SS",
"register": true
}
],
i solved it changing the code,also,my condition expression was wrong...here is what it looks like.
'use strict';
const AWS = require('aws-sdk');
var today = new Date();
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
var hour = (today.getHours()-5) + ":" + today.getMinutes() + ":" + today.getSeconds();
exports.handler = async (event,context) => {
const documentClient = new AWS.DynamoDB.DocumentClient();
let responseBody = "";
let statusCode = 0;
var params = {
TableName:"SomeTable",
Key: { badgeNumber : '0000' },
UpdateExpression: "set assistance[0].register = :n,assistencia[0].date = :date,assistencia[0].hour = :hour",
ExpressionAttributeNames: {
'#asi': 'assistance',
'#reg': 'register'
},
ConditionExpression: "(#asi[0].#reg = :p)",
ExpressionAttributeValues:{
":n":true,
":p":false,
":date":date,
":hour":hour
},
ReturnValues:"UPDATED_NEW"
}
try {
const data = await documentClient.update(params).promise();
responseBody = JSON.stringify(data);
statusCode = 204;
} catch (err) {
responseBody = `Unable to update product: ${err}`;
statusCode = 403;
}
const response = {
statusCode: statusCode,
headers: {
"Content-Type": "application/json"
},
body:responseBody
}
return response
}
this changes the nested values inside my dynamoDB table,if you dont have any its pretty straight forward.
I am trying to retrieve data (Image) from the Google Spreadsheet in Javascript:
Image of the Error:
sheets.spreadsheets.values.get({
auth: jwtClient,
spreadsheetId: SPREADSHEET_ID,
range: 'Sheet1',
includeValuesInResponse: true,
}, function(err, result) {
if(err) {
// Handle error.
console.log(err);
} else {
console.log('%d cells appended.', JSON.stringify(result, null, 2));
}
});
I am receiving an error on the code.
You want to retrieve hyperlinks from "Sheet1" of a Spreadsheet. If my understanding is correct, how about this modification?
Modification point:
You can retrieve the hyperlinks from a sheet using sheets.spreadsheets.get. In this case, sheets/data/rowData/values/hyperlink is used as the fields.
Modified script:
sheets.spreadsheets.get({
auth: jwtClient,
spreadsheetId: SPREADSHEET_ID,
ranges: 'Sheet1',
fields: "sheets/data/rowData/values/hyperlink",
}, function(err, result) {
if (err) {
// Handle error.
console.log(err);
} else {
console.log('%d cells appended.', JSON.stringify(result, null, 2));
}
});
Result:
When no error occurs, the object like below is returned.
{
"sheets": [
{
"data": [
{
"rowData": [
{
"values": [
{
"hyperlink": "https://sample.com/img1.jpg"
}
]
},
{
"values": [
{
"hyperlink": "https://sample.com/img2.jpg"
}
]
},
{},
{},
{},
]
}
]
}
]
}
Note:
This modified script supposes that you can use Sheets API.
I couldn't understand about console.log('%d cells appended.', JSON.stringify(result, null, 2));. If the error occurs at this line, please try the following script.
console.log(JSON.stringify(result.data, null, 2));
Reference:
spreadsheets.get
If I misunderstand your question, I'm sorry.
I figure it out:
async.series([
function makeAnAuthorizedApiCall(callback){
var {google} = require('googleapis');
var sheets = google.sheets('v4');
const storage = new Storage({ projectId: PROJECT_ID });
const jsonCredentialsFile = storage.bucket(BUCKET_NAME).file(SERVICE_ACCT_JSON_FILE);
retrieveFromGCStorage(jsonCredentialsFile).then(creds => {
console.log("Credentials successfully obtained from Google Cloud Storage");
var jwtClient = new google.auth.JWT(
creds.client_email,
null,
creds.private_key,
API_SCOPES, // an array of auth scopes
null
);
jwtClient.authorize(function (err, tokens) {
if (err) {
console.log(err);
return;
}
});
I am creating an application in which I want to use some data from a JSON, which is generated by another js file. Here is the code which is generating JSON
var request = require('request');
module.exports = {
foo:
request('https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/c1d1e5d6-fe5c-42de-8713-60f272a3b63e?subscription-key=d3d3e4dfa8744be9b4ae47558df8fc5a&timezoneOffset=0&verbose=true&q=hey',function (error, response, body) {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
console.log(body);
})
};
I am interested in body object, which is giving following contents -
{
"query": "hey",
"topScoringIntent": {
"intent": "Help",
"score": 0.500165462
},
"intents": [
{
"intent": "Help",
"score": 0.500165462
},
{
"intent": "None",
"score": 0.10364107
},
{
"intent": "SearchHotels",
"score": 0.00249445555
},
{
"intent": "ShowHotelsReviews",
"score": 9.451727E-06
}
],
"entities": []
}
Now I want to access value of intent from topScoringIntent element. That to in another JS file. I tried using body[1].intend but it gives undefined.
I am very new to javascript and need very basic code to do this. Please give some suggestions on this. Also plz tell me if this can be solved by body-parser and if yes then how?
Update - Here is the code where I want to use body['topScoringIntent'].intent as global.
require('dotenv-extended').load();
var builder = require('botbuilder');
var restify = require('restify');
var Store = require('./store');
var spellService = require('./spell-service');
var request = require('request');
var myJSON = require("JSON");
var fs = require('fs');
//var window = window;
var request = require("request");
var myJSON = require("JSON");
var globalVar = [];
// Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log('%s listening to %s', server.name, server.url);
});
// Create connector and listen for messages
var connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
server.post('/api/messages', connector.listen());
function getMyBody(url, callback) {
request({
url: 'https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/c1d1e5d6-fe5c-42de-8713-60f272a3b63e?subscription-key=d3d3e4dfa8744be9b4ae47558df8fc5a&timezoneOffset=0&verbose=true&q=hey',
json: true
}, function (error, response, body) {
if (error || response.statusCode !== 200) {
return callback(error || {statusCode: response.statusCode});
}
global.topScoringIntent = body['topScoringIntent'].intent;
//if(body['topScoringIntent'].intent == 'Help');
//console.log('yay');
callback(null, body);
});
}
getMyBody('https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/c1d1e5d6-fe5c-42de-8713-60f272a3b63e?subscription-key=d3d3e4dfa8744be9b4ae47558df8fc5a&timezoneOffset=0&verbose=true&q=hey', function(err, body) {
if (err) {
console.log(err);
}
})
if(body['topScoringIntent'].intent == 'Help');
console.log('success');
This should work for you
console.log(response.topScoringIntent.intent);
body.topScoringIntent.intent will return 'Help'.
To use it globally you can set a var :
var body = {
"query": "hey",
"topScoringIntent": {
"intent": "Help",
"score": 0.500165462
},
"intents": [
{
"intent": "Help",
"score": 0.500165462
},
{
"intent": "None",
"score": 0.10364107
},
{
"intent": "SearchHotels",
"score": 0.00249445555
},
{
"intent": "ShowHotelsReviews",
"score": 9.451727E-06
}
],
"entities": []
}
var result = body.topScoringIntent.intent;
And then use result somewhere else :
console.log(result);