I have a mongo db that has countries and their associating cities. I want to pull the countries from the db, and put that data in a HTML drop down selection list.
I have the below in mongodbActions.js
used to connect to my mongodb instance, and do the querying and returning of the countries.
const {MongoClient} = require('mongodb');
const uri = "mongodb://127.0.0.1:27017";
const client = new MongoClient(uri);
const Promise = require('rsvp').Promise;
// exporting functions
module.exports = {
mongodbConn: async function() {
try {
// Connect to the mongodb server
await client.connect();
// Establish and verify connection
await client.db("admin").command({ ping: 1 });
console.log("Successfully connected to mongo DB.");
} catch (e) {
console.error(e);
} finally {
await client.close();
console.log("Successfully closed connection to mongo DB.");
}
},
mongodbGetCountries: function() {
return new Promise(function(resolve, reject) {
const dbo = client.db('mydb').collection('countries_cities');
let dbCountries = dbo.distinct('country', function(err, dbCountries) {
if (err) {
reject(err);
} else {
resolve(dbCountries);
}
});
});
},
};
I made use of Promises, as using an async function, and trying to return the value, just resulted in a Promise { <pending> }
when trying to access it in my server.js
And then I have server.js
which has contents:
// load the express module
const express = require('express');
// load boad-parser module
const bodyParser = require('body-parser');
const mongodbActions = require('./static/scripts/mongodbActions')
console.log(mongodbActions)
// init db connection
mongodbActions.mongodbConn()
// get countries from db
let dbCountries = mongodbActions.mongodbGetCountries().then(function (items) {
console.info('The promise was fulfilled with items!', items);
return items
}, function(err) {
console.error('The promise was rejected', err, err.stack);
});
console.log('server side countries:')
console.log(dbCountries)
const index = 'index.pug';
const app = express();
app.use(bodyParser.urlencoded({extended: true}))
app.use(express.urlencoded({extended: true}))
app.use(express.static(__dirname '/static'));
// index page
app.get('/', function (req, res) {
console.log(req.url);
// weather info / data -> display set to on
let weatherVisibilty = 'visibility_on';
let countryList = dbCountries
res.render(index, {
countryList: countryList,
setVisibility: weatherVisibilty
});
})
The below block of code displays the countries in a list, like I want.
// get countries from db
let dbCountries = mongodbActions.mongodbGetCountries().then(function (items) {
console.info('The promise was fulfilled with items!', items);
return items
}, function(err) {
console.error('The promise was rejected', err, err.stack);
});
i.e.
The promise was fulfilled with items! [
'AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AO', 'AQ', 'AR',
'AS', 'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE',
'BF', 'BG', 'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ',
'BR', 'BS', 'BT', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF',
'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU',
'CV', 'CW', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO',
'DZ', 'EC', 'EE', 'EG', 'EH', 'ER', 'ES', 'ET', 'FI', 'FJ',
'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GG',
'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT',
'GU', 'GW', 'GY', 'HK', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE',
... 146 more items
]
However the below block, which I would like it to be the value of items
from above.
console.log('server side countries:')
console.log(dbCountries)
Returns the below:
server side countries:
Promise {
_id: 1,
_label: undefined,
_state: undefined,
_result: undefined,
_subscribers: []
}
So that is NOT the list of countries I want.
Which I want to pass to my pug file: index.pug
to be the contents of my drop down selection list.
Please note that I am quite a noob with javascript and mongodb.
Your assistance and guidance will be very much appreciated.
CodePudding user response:
You cannot get the data from async function outside the scope of that function itself. You can read this answer on SO to better understand how async calls work.
That's why console.log(dbCountries)
always return the promise.
I would suggest you to use async/await
and modify your GET
route
app.get('/', async (req, res) => {
console.log(req.url);
// weather info / data -> display set to on
let weatherVisibilty = 'visibility_on';
let dbCountries = await mongodbActions.mongodbGetCountries();
let countryList = dbCountries
res.render(index, {
countryList: countryList,
setVisibility: weatherVisibilty
});
})