1

In the following code I'm just accessing some data from mongodb and storing it in a variable.Now I want to use this variable out of mongodb.connect() function.But when I'm trying it simply showing output as undefined.

I know it is javascript asynchronous stuff.I've gone through several websites regarding callbacks,promises and async/await but I'm not able to understand any of those topics.

Can anyone please provide some simple modifications to my code.

app.get('/',function(req,res){
    var data;
    mongodb.connect(url,{useNewUrlParser:true},(err,db)=>{
        var dbo=db.db('pract')
        var cursor=dbo.collection('samp').find({_id:1410})
        cursor.forEach(function(doc){
            data=doc;
        })
    }) 
    console.log(data)
    res.end()
})

Expected output : {name:'vasu',age:20}

Actual output : undefined

2 Answers 2

1

I would recommend you to use the new async await functionality introduced in more recent Javascript versions to start with. This form is easier to reason about since it looks like a normal synchronous code. Grasping Javascript's async nuances will take some time, but eventually you'll need it to understand how Javascript works using multiple async methods: Promises, callbacks, etc.

The shortest async/await code using express & MongoDB that I can come up with is this one:

const MongoClient = require('mongodb').MongoClient
const express = require('express')
const app = express()
var conn

app.get('/', async (req, res) => {
  var output = await conn.db('test').collection('test').find().toArray()
  res.send(output)
})

var run = async function() {
  conn = await MongoClient.connect('mongodb://localhost:27017/test', {useNewUrlParser: true})
  await app.listen(3000)
  console.log('listening on 3000')
}

run()

Using curl "http://localhost:3000" should print the content of the test collection in the test database.

Some things to note:

  • conn is a global variable to allow the MongoDB driver to properly use connection pooling. Connect once and reuse the connection everywhere. Don't keep connecting to the database for every request.
  • The main run() method sets up the database connection, then starts listening. This way you're ensuring that the database is ready to go. Otherwise your app can start listening before the database is ready.
  • The example code above does not have any error handling method. In real code, you should use try {...} catch {...} as needed.

This code was tested with node 12.4.0, MongoDB node driver 3.2.7, and express 4.17.1

If you find that this code doesn't work, please make sure that you can connect to the database.

Sign up to request clarification or add additional context in comments.

Comments

0

once you get the GET request your app is connecting to database. this is an async work. so it will take some time to get the result. But console.log is not gonna wait for this async operation.

because connecting to database operation will be send to event loop. console.log has higher precedence over event loop. so console.log will be executed first and during the execution, data has no value so it returns undefined.(I simply touched event loop, this is what you should know regarding your question ).

Solution:

app.get('/',function(req,res){
    //var will make it global, avoid using var.
    let data;
    mongodb.connect(url,{useNewUrlParser:true},(err,db)=>{
        var dbo=db.db('pract')
        var cursor=dbo.collection('samp').find({_id:1410})
        cursor.forEach(function(doc){
            data=doc;
            console.log(data)
          //we are inside the for each function which is inside the callback db function. 
          //that means console.log is inactive till connection is successfully done. 
          //find function is also async function but console.log cannot access to data from here. 
         //it can access only one level above function's variables. 
         //forEach function is sync so it will run the data=doc first then console.log the data. 
         //make sure you already have the data inside the connected database.
        })
    }) 

    res.end()
})

this syntax is very old. try to learn promise and async/await

Comments

Your Answer

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.