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

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

Related

How to scan dynamoDB in lambda?

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

why is not working properly async.each nodejs?

I'm trying to use async.each function to get an array with my results from two queries. After that, I need to render this results in a web page.
The async.each function calcule the variable results properly, but, I am not be able to export this variable outside the function and render it and I don't understand why.
Here I attached the code, where I tested it. I realized that when I call "callback1" the function(error) is not working and I don't get the variable list in the console (so I won't be able to render it later on). Please I would be grateful if someone could help me with that. Thanks a lot.
var list = [];
async.each(data,
function(elem, callback1){
var classgene = '';
var custom_gene = {};
custom_gene = {Name_Gene: elem['Name_Gene']};
if (elem['Type_Gene'] == "reference") {
async.waterfall([
function(callback2){
var id = elem['Id_Genes'];
geneModel.getGenesRefClass(id, function(error, data2){
classgene = data2[0]['Class_Name'];
custom_gene['classgene'] = classgene;
callback2(custom_gene);
});
},
], function(custom_gene, err){
list.push(custom_gene);
console.log(list);
callback1();
});
}
}, function(err){
// if any of the saves produced an error, err would equal that error
if(err){
console.log(list);
}else{
console.log(list);
}
});
Your code has a few problems:
It's not calling callback2() properly. It should be callback2(null, custom_gene) (the first argument is reserved for errors, or null if there aren't any). Preferably, you should also check for error being returned by geneModel.getGenesRefClass();
The previous issue also means that you need to swap the argument of function(custom_gene, err) (it should become function(err, custom_gene));
When elem['Type_Gene'] does not equal "reference", you should still call callback1(), otherwise async.each() doesn't know that the code is done;
So the code would become something like this:
var list = [];
async.each(data, function(elem, callback1) {
var classgene = '';
var custom_gene = { Name_Gene : elem['Name_Gene'] };
if (elem['Type_Gene'] == "reference") {
async.waterfall([
function(callback2) {
var id = elem['Id_Genes'];
geneModel.getGenesRefClass(id, function(error, data2){
if (error) return callback2(error);
classgene = data2[0]['Class_Name'];
custom_gene['classgene'] = classgene;
callback2(null, custom_gene);
});
},
], function(err, custom_gene) {
// If you want to propagate errors, uncomment the following:
// if (err) return callback1(err);
list.push(custom_gene);
console.log(list);
callback1();
});
} else {
callback1();
}
}, function(err){
// if any of the saves produced an error, err would equal that error
if (err) {
console.log('An error occurred!', err);
}
console.log(list);
});

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

A function that has nested callback functions does not return values [duplicate]

This question already has an answer here:
How to return value from Node.js function which contains DB query [duplicate]
(1 answer)
Closed 8 years ago.
I have a function inside of which there is a nested callback function structure. I want that first "mother" function to return a certain value, after it's been calculated in the callback functions sequence. However. it doesn't really work. Here's a simplified version of the code, do you think you could help?
console.log(finalResult());
function finalResult() {
var finalanswer = firstFunction(secondFunction);
function firstFunction (callback) {
var notion = 1;
callback(null, notion);
}
function secondFunction (err, notion) {
if (err) console.log(err);
var answer = notion + 1
return answer;
}
return finalanswer;
}
Thank you!
**UPDATE - THE ORIGINAL CODE**
return getContexts(makeQuery);
function getContexts (callback) {
dbneo.cypherQuery(context_query, function(err, cypherAnswer){
if(err) {
err.type = 'neo4j';
return callback(err);
}
// No error? Pass the contexts to makeQuery function
return callback(null,cypherAnswer);
});
}
function makeQuery (err,answer) {
// Error? Display it.
if (err) console.log(err);
// Define where we store the new contexts
var newcontexts = [];
// This is an array to check if there are any contexts that were not in DB
var check = [];
// Go through all the contexts we received from DB and create the newcontexts variable from them
for (var i=0;i<answer.data.length;i++) {
newcontexts.push({
uid: answer.data[i].uid,
name: answer.data[i].name
});
check.push(answer.data[i].name);
}
// Now let's check if there are any contexts that were not in the DB, we add them with a unique ID
contexts.forEach(function(element){
if (check.indexOf(element) < 0) {
newcontexts.push({
uid: uuid.v1(),
name: element
});
}
});
return newcontexts;
}
You're setting finalanswer equal to the return of firstFunction however, if you look at the body of firstFunction, it does not return anything. The last line of firstFunction should be:
return callback(null, notion);
I quickly tested this in the Chrome console and it seems to work as expected and logs 2 to the console.
UPDATE
Now that the original code has been posted I would update the code as such:
// call getContexts with a callback when complete
getContexts(function(err, contexts){
console.log(err);
console.log(contexts);
});
function getContexts (callback) {
dbneo.cypherQuery(context_query, function(err, cypherAnswer){
if(err) {
err.type = 'neo4j';
return callback(err);
}
// No error? Pass the contexts to makeQuery function
var contexts = makeQuery(null,cypherAnswer);
// we have our answer, call the callback
callback(null, contexts);
});
}
function makeQuery (err,answer) {
// Error? Display it.
if (err) console.log(err);
// Define where we store the new contexts
var newcontexts = [];
// This is an array to check if there are any contexts that were not in DB
var check = [];
// Go through all the contexts we received from DB and create the newcontexts variable from them
for (var i=0;i<answer.data.length;i++) {
newcontexts.push({
uid: answer.data[i].uid,
name: answer.data[i].name
});
check.push(answer.data[i].name);
}
// Now let's check if there are any contexts that were not in the DB, we add them with a unique ID
contexts.forEach(function(element){
if (check.indexOf(element) < 0) {
newcontexts.push({
uid: uuid.v1(),
name: element
});
}
});
return newcontexts;
}

Categories