Home > front end >  mongodb query data to html drop down
mongodb query data to html drop down

Time:03-11

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 
    });
})
  • Related