How to scan dynamoDB in lambda? - javascript

so I have a table of 10 items, each item has about 5 keys (name,experience,level, etc). Now, I want to scan that table, get each item as an object and add it to an array and then JSON stringify that array and return it.
I just need help with the scanning code and getting all items and putting it into an array.
Here's my code I have currently.
var dynamodb = new AWS.DynamoDB.DocumentClient();
exports.handler = function(event, context, callback)
{
var returnArray = {
"cards": {}
}
getCards();
function getCards() {//Not sure how to write this function
var params = {
TableName : "toBeApprovedTable",
Key: {//not sure what to put here, since I want all items, and not searching through keys.
},
};
dynamodb.scan(params,function(err,data)
{
if(err)
{
console.log("error in scanning");
}
else
{
console.log("scanning success!");
//Not sure what to do here.
}
});
}
};

I figured it out after scrapping through Google + AWS docs.
Here is how to scan a table for all elements in the table. My return is a map, which contains an array of elements. Each element is a map of my object.
exports.handler = function(event, context, callback)
{
var returnArray = {
"cardsToBeApproved":[]
};
getCards();
function getCards() {//Not sure how to write this function
var params = {
TableName : "toBeApprovedTable"
};
dynamodb.scan(params,onScan);
}
function onScan(err,data)
{
if(err)
{
console.log("unable to scan table");
}
else
{
console.log("scan succeeded");
data.Items.forEach(function(card)
{
console.log("my card name is " + card.name);
var cardStringified = JSON.stringify(card);
returnArray.cards.push(card);
});
callback(null,JSON.stringify(returnArray));
}
}
};

Related

Replace and update IDs using JavaScript stored procedure

Background:
I need to create a stored procedure in JavaScript (within CosmosDB) where: For every Feedback document, replace/update Feedback.id with new id
var NewID = "5678"
{
"Feedbacks" : [
{
"id": "1234"
}
{
"id": "1234"
}
]
}
This is what I am doing:
I have created a function called UpdateID and set the parameters to OldID and NewID. I am saying iterate through the document, and for every OldID value,, replace with the NewID. I am moreso familiar with Python so this is a bit different for me and I am not sure this is the correct approach.
For every iteration in doc.Feedbacks:
function UpdateID(OldID, NewID) {
if (Feedbacks.id = "OldID")
}
Any suggestion will be helpful
There are a handful of ways to write the javascript, but here's one way that should get on the right track:
function UpdateID(oldID, newID) {
//get just the records that need updating
var isAccepted = __.filter(
function(doc) {
return doc.Feedbacks && doc.Feedbacks.findIndex(function(feedback){
return feedback.id == oldID
}) > -1;
},
function (err, feed, options) {
if (err) throw err;
// Check the feed and if empty, set the body to 'no docs found'
if (!feed || !feed.length) {
var response = getContext().getResponse();
response.setBody('no docs found');
}
else {
//update the documents that have the old id
UpdateDoc(oldID, newID, feed)
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
//function based on https://stackoverflow.com/questions/36009939/documentdb-updating-multiple-documents-fails
function UpdateDoc(oldID, newID, documents) {
console.log("updating " + documents.length + " docs")
if (documents.length > 0) {
var document = documents[0];
// DocumentDB supports optimistic concurrency control via HTTP ETag.
var requestOptions = { etag: document._etag};
document.Feedbacks = document.Feedbacks.map(function(feedback){
if(feedback.id === oldID) {
feedback.id = newID;
}
return feedback;
});
// Update the document.
var isAccepted = __.replaceDocument(document._self, document, requestOptions, function(err, updatedDocument, responseOptions) {
if (err) {
responseBody.error = err;
throw err;
}
});
// If we hit execution bounds - throw an exception.
if (!isAccepted) {
responseBody.log += "Update not accepted";
response.setBody(responseBody);
}
else {
documents.shift();
if(documents.length > 0){
UpdateDoc(oldID, newID, documents);
}
}
}
}

Comparing input value with value of an array in AngularJS

I have a problem with the validation about existing values. I don't know how to compare two values and add the new value only, when it isn't exist in the Database. I've tried with angular.forEach() but it adds the new object always when the compare (what I'm doing with angular.equals()) isn't false and thats wrong. The object have to be only one time in the database.
Here is my create function:
$scope.createItem = function (createItem) {
//here I have to define a query to compare createItem.lname with the table list (array items from the db) in the view.
//That was the code:
angular.forEach(nameslist, function (value) {
if (angular.equals(createItem.lname, value.lname)) {
CrudService.create(createItem).then(
function () {
//success code
$scope.createItem = null;
},
function (err) {
//error code
});
}
}
});
}
Can anyone give me some help.. I don't know how to solve it.
var itemAbsent = namelist.map(function(value){
return value.name;
}).indexOf(createItem.name) < 0;
if (nameAbsent){
CrudService.create(createItem).then(
function () {
//success code
$scope.createItem = null;
},
function (err) {
//error code
});
}
}

Node JS Loop Through Array Before Creating Property

I have a JSON input which contains data linking it to a secondary model (Users). I need to loop through listingData.Agents to get the index ID and then look up this index id to get the user. I push this to the user id to an array but due to the async the array is blank when the create property function is run. How you manipulate and get data from the array and then run the create once all your data is in place.
Thanks.
exports.createProperty = function(req,res,next) {
var listingData = req.body;
listingData.User = [];
_.forEach( listingData.Agents , function(n, key) {
User.findOne({ agentId : n.AgentId},function(err,user) {
listingData.User.push(user._id);
});
});
Property.create(listingData, function(err,property) {
if (err) {
res.status(400);
return res.send({reason:err.toString()});
}
res.send(req.property);
})}
If you don't mind introducing new library into your code, node-async could solve your problem.
Using node-async, you code would be:
var async = require('node-async')
exports.createProperty = function(req,res,next) {
var listingData = req.body;
listingData.User = [];
async.each(listingData.User,
function(n, key) {
User.findOne({ agentId : n.AgentId},function(err,user) {
listingData.User.push(user._id);
});
},
function (asyncErr){
//handle asyncErr first
Property.create(listingData, function(err,property) {
if (err) {
res.status(400);
return res.send({reason:err.toString()});
}
res.send(req.property);
});
});

recursive in callback functions

I have a function with callback, where I'm using "listTables" method of dynamoDB, which returns just 100 table names and if there is anymore tables, it returns another field called "LastEvaluatedTableName" which we can use in our new query in listTables to query another 100 tables from the mentioned "LastEvaluatedTableName"; how can I have recursion in callbacks in javascript in this logic?
I have tried the following which is not correct:
module.exports.ListTables = function (start, callback) {
var params;
if (start) {
params = {
"ExclusiveStartTableName": start
};
}
dynamodb.listTables(params, function (err, data) {
var totalData = [];
totalData.push(data);
if (data.LastEvaluatedTableName) {
data = module.exports.ListTables(data.LastEvaluatedTableName);
}
callback(err, totalData);
});
}
Please let me know if you need more clarifications!
Thanks!
You need to concat your data, not replace it each time:
dynamodb.listTables(params, function (err, data) {
if (data.LastEvaluatedTableName) {
data.concat(module.exports.ListTables(data.LastEvaluatedTableName));
}
callback(err, data);
});
UPDATE
Based on the info from the comment, sounds like you need something like this:
module.exports.ListTables = function (start, callback, totalData) {
var params;
if (start) {
params = {
"ExclusiveStartTableName": start
};
}
if (!totalData) {
totalData = [];
}
dynamodb.listTables(params, function (err, data) {
totalData = totalData.concat(data.TableNames);
if (data.LastEvaluatedTableName) {
module.exports.ListTables(data.LastEvaluatedTableName, callback, totalData);
}
else {
callback(err, totalData);
}
});
}

Push new field and value to json array object in node.js

I'm new to node.js. I need to display Name in jqgrid, but I stored only id of one document into another document.
Example
I have 2 documents like Student master and student mark document. I have to display mark details in jqgrid. In mark document I stored student id instead of name. How do I fetch the name and send a new object to jqgrid?
My code is as follows:
exports.getAllstudentsmark = function(req, callback)
{
studentsmarks.find(function(error, studentsmarks_collection) {
if( error ) callback(error)
else {
studentsmarks_collection.toArray(function(error, results) {
if( error ) callback(error)
else {
newresult = results;
for(i=0;i<results.length;i++)
{
newresult[i]['studentname'] = getStudentName(results[i].studentid);
}
console.log(newresult);
callback(null, newresult)}
});
}
});
}
var getstudentObjectId = function(id)
{
return student.db.bson_serializer.ObjectID.createFromHexString(id);
}
var getStudentName = function(id)
{
student.findOne({_id: getstudentObjectId (id)}, function(e, o){
console.log(o.name);
return o.name;
});
}
newresult[i]['studentname'] is always getting undefined. But if I log into getStudentName function I can get answer into getStudentName function.
My callback function is only getting this problem. How to resolve and get my result in an easy way. Please help any one.
try this inside your for loop
newresult.push({'studentname': getStudentName(results[i].studentid) });
exlpanation:
by the time you access newresult[i] it doesn't exist, so accessing studentname field of it is impossible
Your problem here is that you are not setting the name of the user into the array, but the return value of student.findOne, since this is an asynchronous method. Maybe try this thing
exports.getAllstudentsmark = function(req, callback)
{
studentsmarks.find(function(error, studentsmarks_collection) {
if( error ) callback(error)
else {
studentsmarks_collection.toArray(function(error, results) {
if( error ) callback(error)
else {
newresult = [];
for(i=0;i<results.length;i++)
{
getStudentName(results[i].studentid, function (studentName) {
newresult.push({studentname: studentName});
})
}
console.log(newresult);
callback(null, newresult)}
});
}
});
}
var getstudentObjectId = function(id)
{
return student.db.bson_serializer.ObjectID.createFromHexString(id);
}
var getStudentName = function(id, callback)
{
student.findOne({_id: getstudentObjectId (id)}, function(e, o){
console.log(o.name);
callback(o.name);
});
}
I hope it helps

Categories