I'm using Node.js, Hapi and MongoDB Native Driver ( node-mongodb-native )
I want to access the db object returned by the get() method from db.js
in my handler in server.js
.
db.js
'use strict'
const MongoClient = require('mongodb').MongoClient
let _db
function connect (url) {
return MongoClient.connect(url, { server: { poolSize: 5 } })
.then((db) => {
_db = db
console.log('Connected to MongoDB:', db.s.databaseName)
})
.catch((e) => {
throw e
})
}
function get () {
return _db
}
function close () {
if (_db) {
console.log('Closing MongoDB connection.')
_db.close()
}
}
module.exports = {
connect,
close,
get
}
server.js
'use strict'
const Hapi = require('hapi')
const Db = require('./db')
const _db = Db.get()
const server = new Hapi.Server()
server.connection({
host: 'localhost',
port: 8080
})
server.route({
method: 'GET',
path: '/',
handler: (req, rep) => {
console.log(_db) // _db is undefined
}
})
Db.connect('mongodb://localhost:27017/test')
.then(() => {
server.start((err) => {
if (err) {
throw err
}
console.log(`Server running at: ${server.info.uri}`)
})
})
.catch((e) => {
console.error(`${e.name}: ${e.message}`)
return
})
The problem is that Db.get()
return undefined
.
Now consider this code instead:
const Db = require('./db')
const server = new Hapi.Server()
...
server.route({
method: 'GET',
path: '/',
handler: (req, rep) => {
const _db = Db.get()
console.log(_db) // the _db object exists
}
})
I don't understand why the first code return undefined as the get() method is called and should store the instance into _db
thus accessible in the handler function.
The value of _db
is assigned in a function passed to then
of a Promise, the execution of this part is deferred to a point in time until the Promise has been resolved. The server.route
is synchronous. It means it will be very likely executed before the Promise has been resolved.
To make it work, wait until the Promise has been resolved:
'use strict'
const MongoClient = require('mongodb').MongoClient
let _db
async function connect (url) {
try {
return await MongoClient.connect(url, { server: { poolSize: 5 } })
} catch (error) {
throw new Error('Could not connect to Mongo instance');
}
}
async function get () {
return _db ? _db : await connect();
}
async function close () {
if (_db) {
console.log('Closing MongoDB connection.')
_db.close()
}
}
module.exports = {
connect,
close,
get
}
and then
'use strict'
const Hapi = require('hapi')
const Db = require('./db')
const _db = await Db.get()
const server = new Hapi.Server()
server.connection({
host: 'localhost',
port: 8080
})
server.route({
method: 'GET',
path: '/',
handler: async (req, rep) => {
const _db = await Db.get();
console.log(_db) // _db will be guaranteed to be a valid object, otherwise an error will be thrown
}
})
Db.connect('mongodb://localhost:27017/test')
.then(() => {
server.start((err) => {
if (err) {
throw err
}
console.log(`Server running at: ${server.info.uri}`)
})
})
.catch((e) => {
console.error(`${e.name}: ${e.message}`)
return
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.