11

I have a mongodb database called pokemon with a collection called pokemons. Here is my attempt to write a function that will do a find() operation in mongodb:

'use strict';
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
// db url
var url = 'mongodb://localhost:27017/pokemon';
exports.getPokemonByName = function (name) {
 MongoClient.connect(url, function(err, db) {
 assert.equal(null, err);
 var cursor = db.collection('pokemons').find({name: name});
 // how to return json? 
 });
};

I then call this function in another file:

var express = require('express');
var router = express.Router();
router.get('/pokedex', function (req, res) {
 res.jsonp(db.getPokemonByName('Dratini'));
})

This link is helpful in showing how to log mongodb data to the console by doing some sort of each() method on the cursor object, but I don't know how to return json through the getPokemonByName function. I tried to define an empty array on the root scope of the getPokemonByName function and push data into that array with each iteration of the .each method show in that link, but I think I still can't return that array because it happens after the fact.

BTW, I'm really just doing this for fun and to learn about MongoDB and Node.js, so I don't want to use or an ODM like Mongoose to do some of this work for me.

E_net4
30.4k13 gold badges117 silver badges154 bronze badges
asked Nov 2, 2015 at 3:11
3

4 Answers 4

11

I was able to answer my question with help from node's native monogodb driver github page: See here.

In essence, what I did was to define my exported function within the MongoClient's connection function. For some reason I thought node exports had to be in the root of the module, but that's not the case. Here's a finished version:

'use strict';
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
// db url
var url = 'mongodb://localhost:27017/pokemon';
var findDocuments = function(db, callback) {
 // Get the documents collection
 var collection = db.collection('pokemons');
 // Find some documents
 collection.find({name: 'Dratini'}).toArray(function(err, docs) {
 assert.equal(err, null);
 // assert.equal(2, docs.length);
 console.log("Found the following records");
 callback(docs);
 });
}
// Use connect method to connect to the Server
MongoClient.connect(url, function(err, db) {
 assert.equal(null, err);
 console.log("Connected correctly to server");
 findDocuments(db, function(docs) {
 console.log(docs);
 exports.getPokemonByName = function() {
 return docs;
 }
 db.close();
 });
});

And then in another file:

var express = require('express');
var router = express.Router();
router.get('/pokedex', function (req, res) {
 res.jsonp(db.getPokemonByName());
});

Of course, this solution requires that I hardcode queries, but I'm okay with that for now. Will cross that bridge when I come to it.

answered Nov 3, 2015 at 0:55

Comments

5

Found a simple tweak for this. Let say the callback to the findOne returns result then you can convert the result to JSON object like this

result = JSON.parse(JSON.stringify(result))

Now you can access the result and its fields simply with the dot operator.

answered Dec 4, 2019 at 9:06

1 Comment

That's rad. Thank you.
1

this may help

var cursor = db.collection('pokemons').find({name:name}).toArray(function(err,arr){
 return arr;
 });
answered Nov 2, 2015 at 3:45

2 Comments

No you cannot return a value inline from an asynchronous call.
This works when querying the MongoDB directly using the mongo shell. However, as Blakes mentioned the actual process of getting results from the database is asynchronous. With recent versions of Node and the Mongo library you should be able to accomplish this with await: let results = await db.collection('pokemons').find({ name }).toArray();.
1

You can use callbacks on find function to return the json. Try

exports.getPokemonByName = function (name,callback) {
 MongoClient.connect(url, function(err, db) {
 assert.equal(null, err);
 var cursor = db.collection('pokemons').find({name: name},function(err,result){
 if(err)
 {
 callback(err,null);
 }
 if(result)
 callback(null,result);
 });
 });
};
router.get('/pokedex', function (req, res) {
 db.getPokemonByName('Dratini',function(err,result){
 if(result)
 {
 res.jsonp(result);
 }
 });
})
answered Nov 2, 2015 at 3:49

3 Comments

the getPokemonByName(name) function still doesn't return anything, though.
check the edit. Using callback now to return the json.
Seems like it should work but produces a circular reference error: TypeError: Converting circular structure to JSON. Can't say why.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.