fetch a particular value using node js and mongodb - javascript

I have to try to fetch a field value from MongoDB using Node.js. But it shows me undefined in my console. My requirement is to print the data in the console or browser from MongoDB using Node.js.
1). This is my node js
this.levelChange = function(req, res, next){
try{
var query = {'level_num':2};
QuizLevel.find(query,function(err,data){
var a = data.min_score;
console.log(a);
res.send(a);
});
}catch(err){
console.log("Error");
return next(err);
}
};
2). This is my js-schema
{
_id:{type:String},
age:{type:Number},
level_num:{type:String},
min_score:{type:String},
max_questions:{type:String}
}
3).This is my console output
undefined
4). This is my JSON data
{
"age":5,
"level_num":1,
"min_score":10,
"max_questions":30
},
{
"age":5,
"level_num":2,
"min_score":12,
"max_questions":33
}

Simply use findOne(find return an array of document) with a project field(return only desired fields).
And don't forget to check the err field !
try{
var query = {'level_num':2};
QuizLevel.findOne(query,{min_score: 1}, function(err,data){
if(err || !data)
{
console.log(err);
return next(err);
}
else
{
var a = data.min_score;
console.log(a);
res.send(a);
}
});
}catch(err){
console.log("Error");
return next(err);
}

I might be incorrect but it looks like you're trying to access object property while the result is a collection, see:
data.min_score // => [{ ... }, { ... }].min_score
vs
data[0].min_score
What you want to achieve is something like:
var scores = data.map((function (item) {
return item.min_score;
});
console.log(scores);
You can always check the type of result with console.log(typeof data) or simply write console.log(data), sometimes console.log(Object.keys(data)) come in handy as well for simple debugging not to mention node-inspector.

Related

.push() not pushing into array with mongodb [duplicate]

I am trying to add status to a response on successful update but I am not able to add the status property to json object of form. Here is my code
apiRouter.post('/forms/update', function(req, res){
if(req.body.id !== 'undefined' && req.body.id){
var condition = {'_id':req.body.id};
Form.findOneAndUpdate(condition, req.body, {upsert:true}, function(err, form){
if (err) return res.send(500, { error: err });
var objForm = form;
objForm.status = "saved successfully";
return res.send(objForm);
});
}else{
res.send("Requires form id");
}
});
and here is the response that I get, notice status is missing
{
"_id": "5580ab2045d6866f0e95da5f",
"test": "myname",
"data": "{\"name\":3321112,\"sdfsd\"344}",
"__v": 0,
"id": "5580ab2045d6866f0e95da5f"
}
I am not sure what I am missing.
Try to .toObject() the form:
Form.findOneAndUpdate(condition, req.body, {upsert:true}, function(err, form){
if (err) return res.send(500, { error: err });
var objForm = form.toObject();
objForm.status = "saved successfully";
return res.send(objForm);
});
Mongoose query result are not extensible (object are frozen or sealed), so you can't add more properties. To avoid that, you need to create a copy of the object and manipulate it:
var objectForm = Object.create(form);
objectForm.status = 'ok';
Update: My answer is old and worked fine, but i will put the same using ES6 syntax
const objectForm = Object.create({}, form, { status: 'ok' });
Another way using spread operator:
const objectForm = { ...form, status: 'ok' }
Try changing res.send(objForm) to res.send(JSON.stringify(objForm)). My suspicion is that the the Mongoose model has a custom toJson function so that when you are returning it, it is transforming the response in some way.
Hopefully the above helps.
Create empty object and add all properties to it:
const data = {};
data._id = yourObject._id; // etc
data.status = "whatever";
return res.send(data);
Just create a container.
array = {};
Model.findOneAndUpdate(condition, function(err, docs){
array = docs;
array[0].someField ="Other";
});

How to update an object using for-of loop in node.js [duplicate]

I am trying to add status to a response on successful update but I am not able to add the status property to json object of form. Here is my code
apiRouter.post('/forms/update', function(req, res){
if(req.body.id !== 'undefined' && req.body.id){
var condition = {'_id':req.body.id};
Form.findOneAndUpdate(condition, req.body, {upsert:true}, function(err, form){
if (err) return res.send(500, { error: err });
var objForm = form;
objForm.status = "saved successfully";
return res.send(objForm);
});
}else{
res.send("Requires form id");
}
});
and here is the response that I get, notice status is missing
{
"_id": "5580ab2045d6866f0e95da5f",
"test": "myname",
"data": "{\"name\":3321112,\"sdfsd\"344}",
"__v": 0,
"id": "5580ab2045d6866f0e95da5f"
}
I am not sure what I am missing.
Try to .toObject() the form:
Form.findOneAndUpdate(condition, req.body, {upsert:true}, function(err, form){
if (err) return res.send(500, { error: err });
var objForm = form.toObject();
objForm.status = "saved successfully";
return res.send(objForm);
});
Mongoose query result are not extensible (object are frozen or sealed), so you can't add more properties. To avoid that, you need to create a copy of the object and manipulate it:
var objectForm = Object.create(form);
objectForm.status = 'ok';
Update: My answer is old and worked fine, but i will put the same using ES6 syntax
const objectForm = Object.create({}, form, { status: 'ok' });
Another way using spread operator:
const objectForm = { ...form, status: 'ok' }
Try changing res.send(objForm) to res.send(JSON.stringify(objForm)). My suspicion is that the the Mongoose model has a custom toJson function so that when you are returning it, it is transforming the response in some way.
Hopefully the above helps.
Create empty object and add all properties to it:
const data = {};
data._id = yourObject._id; // etc
data.status = "whatever";
return res.send(data);
Just create a container.
array = {};
Model.findOneAndUpdate(condition, function(err, docs){
array = docs;
array[0].someField ="Other";
});

node.js token deletion promise

I have a delete route for my api that deletes tokens stored in our mongodb. I am currently writing a check that makes sure the token is not associated with another object before it is processed for deletion.
function checkTokenIsNotUsed(req) {
console.log('TEST ' + req.params.token);
objectDB.findObject('artefact', {"data.token": req.params.token})
.then(function(result) {
console.log('findObject result' + result);
if (isDefined(result)) {
console.log('Artefact Exists');
serverError(res, 'Cannot delete token as it is associated with an artefact');
} else {
console.log('Token not being used by an artefact, okay for deletion');
};
})
.catch(function(err){
console.error('Token CHECK DELETE error: '+err.message);
serverError(res, 'err.message');
});
return(result)
};
//
// Token deletion
//
app.delete('/:token', function(req, res, next) {
checkTokenIsNotUsed(req)
.then(function(results){
return tokenModel.findOne({token: req.params.token});
})
As it stands, when I hit the route the checkTokenIsNotUsed function is called, and prints 'TEST + <token>' to the console, and then kicks out to cannot read property 'then' of undefined.
I have checked my query in the mongo shell independently of the platform interface that I am using and the query works as expected. The api route also works as expected without the checkTokenIsUsed function active.
Any ideas as to why the promise for objectdb.findObject() is not returning a result? It is intended to return a list of objects or nothing at all, and does as expected in other locations in this file.
-findObject is properly exported + imported from its respective location
-the query is correctly structured and works in mongo shell.
-the token itself is being printed just before this function is run, so checkTokenIsNotUsed is getting called and being executed.
-I don't really care that the conditional is just printing to the console at the moment, as my objective right now is to merely enter into that part of the function.
EDIT added
findObject = function(objType, query, options) {
return new Promise(function(resolve,reject) {
var populateOptions;
var findQuery = {};
var findOptions = {
sort: 'metaData.createTS',
page: 1,
limit: 50
};
var objectDef = getObjectDef(objType);
if (!isDefined(objectDef)) return resolve(null);
// Make sure query exists and has objType set
if (isDefined(query)) findQuery = query;
if (!isDefined(findQuery.objType)) findQuery.objType = objType;
if (isDefined(options)) {
if (isDefined(options.sort)) findOptions.sort = options.sort;
if (isDefined(options.page)) findOptions.page = toInt(options.page);
if (isDefined(options.limit)) findOptions.limit = toInt(options.limit);
}
if (isDefined(objectDef.populate)) populateOptions = objectDef.populate;
else populateOptions = "";
objectDef.model.find(findQuery, null, findOptions)
.populate(populateOptions)
.exec(function(error, list) {
if (error) reject(error);
else resolve(list);
});
});
};

Get note contents with evernote api in node.js server

I'm working on my private project using Evernote API and node.js(express.js)
I successfully got an requestToken and accessToken using jsOAuth Module and I got the note guid from noteMetaData too.
however, when I use
noteStore.getNote
function, It continuously fails.
with this errormessage :
Error in NodeBinaryHttpTransport.flush: Binary protocol does not support synchronous calls
however I already inserted my callback function.
I checked API Docs but not specific doc for javascript. Arguments are different. I checked what kind of arguments does noteStore.getNote wants by logging Function.length, but it was 0.
here is my code.
I use express and router is require('express').Router();
gb is global object that contains my developer token and secret.
router.get('/users',function (request,response){
var parsedUrl = url.parse(request.url);
console.log('search is:'+parsedUrl.search)
client.getAccessToken(
gb.oauthToken,
gb.oauthSecret,
getOauthVerifier(parsedUrl.search),
function(error, oauthAccessToken, oauthAccessTokenSecret, results) {
if(error) {
console.log("error\n\n\n");
console.log(error);
}
else {
console.log('successfully get an access token.');
var accessedClient = new Evernote.Client({
token: oauthAccessToken,
sandbox:true
})
var noteStore = accessedClient.getNoteStore("https://sandbox.evernote.com/edam/note/");
noteStore.listNotebooks(function(err, notebook){
var filter = new Evernote.NoteFilter();
filter.notebookGuid = notebook[0].guid;
console.log('filter is..',filter);
var resultSpec = new Evernote.NotesMetadataResultSpec();
resultSpec.includeTitle = true;
resultSpec.includeContentLength = true;
resultSpec.includeCreated = true;
resultSpec.includeAttributes = true;
noteStore.findNotesMetadata(filter, 0, 100, resultSpec, function(err, notesMeta) {
if (err) {
console.error('err',err);
}
else {
console.log("Found "+notesMeta.notes.length+" notes in your default notebook . . .")
for (var i in notesMeta.notes) {
var noteGuid = notesMeta.notes[i]['guid'];
var note = noteStore.getNote(
noteGuid,{
withContent: true
},
function(err, results){
if(err) return console.error("Error")
console.log(results);
response.end();
})
}
}
});
})
}
);
})
It was a stupid question. I found a solution.
All I Needed to do was sticking to the parameter guided in the API docs.
noteGuid,{
var note = noteStore.getNote( true, true, true,true
},
function(err, results){
if(err)
return console.error("Error")
console.log(results);
response.end();
})

nodejs and MongoDB's collection.find() does not respond

I have about 30,000 documents in a MongoDB collection. And have been stuck in developing a node.js script to retrieve only the records with a specific string key-value pair.
this query on MongoDB server returns me the exact results I've been looking for:
db.getCollection('posts').find({authorName: "Ashwin-kumar"})
Returns me about 33 documents instantly. Likewise I've about 40 authors with different names.
Here's my node.js script to retrieve posts by authorName (Yes, it is based on Name, a string, as there is no ID for these authors :( ):
var fs = require('fs'),
request = require('request'),
async = require("async"),
assert = require('assert');
_ = require('lodash'),
MongoClient = require('mongodb').MongoClient;
var db, postsCollection, postCol;
async.series([dbConnect, checkCollection, createMeta, dbClose], function(){
console.log("Executed all calls in series.");
process.exit(0);
});
function dbConnect(callback){
MongoClient.connect("mongodb://localhost:27017/jPosts", function(pErr, pDb) {
if(pErr) {
console.dir(pDb);
return 0;
}
db = pDb;
callback();
});
}
function dbClose(callback){
db.close(true, function (err) {
if (err) console.error(err);
else console.log("close complete");
callback();
});
}
function checkCollection(callback) {
db.collection('posts', function(err, collection) {});
postsCollection = db.collection('posts');
postCol = db.collection('posts');
callback();
}
function createMeta(callback){
var meta = [];
postsCollection.aggregate([
{
$group : {_id : "$authorName"}
}]).toArray(function(err, result) {
assert.equal(err, null);
async.forEachLimit(result, 1, function(pPost, callback) {
getPosts(pPost._id, callback);
}, function(err) {
console.log(err);
callback();
});
});
}
function getPosts(pAuthor, callback){
var cursor = postCol.find({ "authorName": pAuthor});
cursor.toArray(function(err,items){
if(err)
callback(err);
else
callback(null, items);
});
}
This does not seem to work for me. cursor.toArray() does nothing but wait forever. Is it because of too many fields in each document?
I tried to get the count of the documents the cursor fetched and it works well.
function getPosts(pAuthor, callback){
var cursor = postCol.find({ "authourName": pAuthor});
cursor.count().then(function(items_count) {
console.log(items_count);
callback();
});
}
Also, I tried the cursor's .each method to iterate the documents fetched. But no luck yet.
function getPosts(pAuthor, callback){
var cursor = postCol.find({ "authourName": pAuthor});
cursor.each(function(err, doc) {
assert.equal(err, null);
if (doc != null) {
console.dir(doc);
} else {
console.log(err);
}
});
}
Am I missing something here? What else can be done to make this work? Is there any issues with the way I'm using async?
P.S: The idea here is to query the dump and generate the PDF's for authours in the jPost collection.
P.S 2: Here's a sample document
{
"_id" : ObjectId("571d36b55672f713fe346a66"),
"id" : 56517,
"authorName" : "Ashwin-kumar",
"comment_count" : 380,
"tagline" : "... Opinions you don't really need",
"vote_count" : 5152,
"exclusive" : null,
"post": [
],
"post_comments" : [
//comment_count objects
],
"date" : "2016-03-27"
}
(I've omitted post & post_comments parts for brevity.)
try this:
var collection = db.collection("collection_name");
collection.find({authourName: "Ashwin-kumar"}).toArray(function (err,items) {
if (err) {
console.dir(err);
} else {
//do something with items array
console.dir(items);
}
});
Did you check what is the value of pAuthor in getPosts? Because when you do aggregation, you receive a collection of objects with _id field (not authourName), so you should do:
// not sure why you need meta array, at least it's not used in the code you provided
meta.push({
author: pPost._id
});
getPosts(pPost._id, callback);

Categories

Resources