반응형
파일 분리를 잘못했을 때 나타날 수 있는 Error
TypeError: Cannot read properties of undefined (reading 'collection')
mongodb.js 파일을 만들고 아래와 같이 db 정보를 export 하면 다른 파일에서 db를 접근할 때 위와 같은 오류가 난다.
const MongoClinet = require('mongodb').MongoClient;
var db;
MongoClinet.connect(
process.env.DB_URL
,(err, client)=>{
if(err) return console.log(err);
db = client.db('DBname');
});
module.exports = db;
왜냐하면 DB 연결 설정은 비동기적으로 처리되므로 연결이 완료되지 않은 상태에서 module.exports = db; 코드가 실행될 수 있다. 그래서 undefined인 db 변수를 exports 했기 때문에 다른 파일에서 db를 사용할 수 없다.
Solution
mongodb.js에 DB 연결 설정하는 함수, DB 정보를 가져오는 함수를 객체로 만들고 app.js(메인 서버 코드)에서는 DB 연결 설정 함수를 호출하고 연결이 정상적으로 완료되면 콜백 함수로 그때 나머지 서버 코드를 호출하도록 하면 된다.
app.js가 아닌 다른 파일에서 db 정보를 얻고 싶으면 getDB함수만 호출하면 된다. 왜냐하면 app.js에서 이미 DB 연결 설정 함수를 호출했고 require은 항상 오직 한 번만 로드가 되기 때문에 db정보를 그대로 쓸 수 있다.
[lib/mongodb.js]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
const MongoClinet = require('mongodb').MongoClient;
let _db;
const connectDB = (callback) => {
MongoClinet.connect(process.env.DB_URL, (err, client) => {
_db = client.db('DBname');
return callback(err);
});
}
const getDB = () => _db;
const disconnectDB = () => _db.close();
module.exports = { connectDB, getDB, disconnectDB };
|
cs |
[app.js]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
const express = require('express');
const app = express();
const MongoDB = require('./lib/mongodb.js');
MongoDB.connectDB((err) => {
if (err) return console.error(err);
// Connect to MongoDB and put server instantiaition code inside
// because we start the connection first
app.listen(process.env.PORT, () => {
console.log(`listening on ${process.env.PORT}`);
});
});
|
cs |
[다른 파일에서 db 정보 얻기]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
var router = require('express').Router();
var MongoDB = require('../lib/mongodb.js');
var db = MongoDB.getDB();
router.get('/', (req, res)=>{
db.collection('post').find().toArray((err, result)=>{
console.log(result);
res.render('list.ejs', {posts : result});
});
});
module.exports = router;
|
cs |
반응형