Почему у вас ошибка:
У вас есть эта ошибка, потому что в DBConfig.js
вы экспортировали products
как функцию:
exports.products = ()=>{
getCollectionFn("products", data=>{ return data})
}
Однако в product.js
, куда вы импортировали products
, вы пытались использовать его как объект , вызывая для него метод .find()
:
// ...other controller codes
products.find({}).toArray(function(err, result) {
if (err) throw err;
return result;
});
// ...other controller codes
Это не будет работать, потому что у вас нет метода .find()
для функции products
, и именно поэтому вы получаете ошибку типа: TypeError: products.find is not a function
.
Исправление:
Чтобы функция products
работала так, как я полагаю, вы этого хотите, вам нужно обновить как способ ее экспорта, так и способ ее использования. Экспорт в DBConfig.js
должен выглядеть примерно так:
// The update to this functions is simply adding a way
// to close the opened MongoDB connection
var getCollectionFn = (CollectionName,callback)=>{
var client = new MongoClient(url);
// The done function simply closes the mongoDB connection
const done = () => {
client.close();
}
client.connect(function(err, db) {
if (err) throw err;
var dbo = db.db(DB_Name);
// Pass the done function to the call back
callback(dbo.collection(CollectionName), done)
});
}
exports.products = (callBack) => {
// Notice the use of a callBack as opposed to what was there before
getCollectionFn("products", callBack);
}
И использование в контроллере продукта должно выглядеть примерно так:
module.exports = productsControllers = {
getAllProducts: (callback) => {
// Note that the actual query is in a callback passed to the
// products function as argument
products((collection, done) => {
collection.find({}).toArray(function(err, result) {
if (err) throw err;
callback(result);
// It's important to call the done method to avoid too many
// open connections
done();
});
})
}
}
Следует отметить, что в отличие от ранее, контроллер getAllProducts
не будет возвращать список продуктов из базы данных, вместо этого вам нужно будет передать обратный вызов от того, кто использует контроллер getAllProducts
, чтобы получить результат запроса базы данных.
Я чувствую, что это постепенно превращается в ад обратного вызова, вы можете спасти себя от этого, используя обещания. Методы соединения и запроса MongoDB могут возвращать обещания для асинхронной операции.