Reputation: 596
Basically what I'm trying to accomplish is pulling the data from a MongoDB database and feed it into my Express.js server. Both of these are ran on the localhost with different addresses. I have tried numerous different methods to get it working and can't seem to get it to work.
Express portion
app.get('/products', function(request, response) {
var query = request.query.keywords;
var promise = new Promise(async (resolve, reject) => {
var productList = await db.getProducts(query);
resolve(productList);
});
promise.then(function(productList) {
console.log(productList); // <--- productList is undefined here
response.json({
productList
});
}).catch('Error retrieving data');
// var productList = Promise.resolve(db.getProducts(query));
// productList.then(products => response.json({products}));
});
MongoDB portion
StoreDB.prototype.getProducts = function(queryParams){
return this.connected.then(function(db){
// TODO: Implement functionality
const collection = db.collection('products');
var productList;
if (!queryParams){
console.log('no queryParams');
collection.find({}).toArray(function(err, docs) {
productList = convertToObject(docs);
// console.log(productList); // <--- productList is defined here
return productList;
});
////////////
Some extra information:
- StoreDB is a functional class with only one property
, connected, which is a promise that gets resolved once the connection to the database has been established
- The Express.js server calls getProducts
which then resolves the promise
- Within the getProducts
call, productList
is defined, but when it returns, the value is undefined
With this being said, I thought that by putting the getProducts
within in a promise, it would wait for the function call to be complete, then resolve it. However, that is not the case. Some insights would be greatly appreciated. Thanks.
SOLVED Thanks to @Renan Le Caro
app.get('/products', function(request, response, next) {
db
.getProducts(request.query.keywords)
.then(productList=>response.json({productList}))
.catch(err=>next(err));
});
StoreDB.prototype.getProducts = function(queryParams){
return this.connected.then(db =>
new Promise((resolve, reject) => {
db
.collection('products')
.find({})
.toArray((err, docs) => err ? reject(err) : resolve(docs))
})
}
Upvotes: 0
Views: 247
Reputation: 5556
getProducts
is already a Promise; you shouldn't need to be wrapping a Promise in another Promise, and that just opens the code up to more places things can go wrong. But Promise.resolve
does not wait for a Promise to resolve; instead, it IMMEDIATELY returns a new Promise that has already resolved with the value you pass it. That's not what you want. And .catch
takes a function to run when the Promise fails, not a string.
Your code should be as simple as this:
app.get('/products', function(request, response) {
var query = request.query.keywords;
db.getProducts(query).then(function(productList) {
console.log(productList);
response.json({
productList
});
}).catch(function() {
response.send('Error retrieving data');
});
});
Or, if you prefer the async/await syntax:
app.get('/products', async function(request, response) {
var query = request.query.keywords;
try {
const productList = await db.getProducts(query);
console.log(productList);
response.json({
productList
});
} catch (err) {
response.send('Error retrieving data');
}
});
Upvotes: 1
Reputation: 365
This is just a promises misuse problem. Here's a fix (not tested).
app.get('/products', function(request, response, next) {
db
.getProducts(request.query.keywords)
.then(productList=>response.json({productList}))
.catch(err=>next(err));
});
StoreDB.prototype.getProducts = function(queryParams){
return this.connected.then(db =>
new Promise((resolve, reject) => {
db
.collection('products')
.find({})
.toArray((err, docs) => err ? reject(err) : resolve(docs))
})
}
Upvotes: 0