Jleibham Jleibham - 7 days ago 5
Javascript Question

How to use express route param to access database object

I'm trying to route different radio sessions/episodes from database queries with express.js. I'm able to grab the route param from the URL in my express route. But I'm unsure how to use the param to query the database for the right object.

I'm able to get this to work by hardcoding the param into my service as shown below with the 'title' variable in service.js. Currently, I only know how to pass variables from express to the view. Is there a way to pass the title param from my express route to the service.js file?

Routes.js

'use strict';

const express = require('express');
const Sessions = require('../models/sessions')
const routes = express.Router();
const apiRoutes = express.Router();

apiRoutes.get('/sessions', (req, res) => {
Sessions.find({}, (err, sessions) => {
if(err) {
return res.status(500).json({message: err.message});
}
res.json({sessions: sessions});
})
});

routes.get('/', (req, res, next) => {
return res.render('index', {title: 'Home'});
});


// I added this bit of code after realizing I needed to use mongoose to query the database. I'm still unsure how to pass the object to my javascript but I'm getting closer.
routes.get('/:title', function (req, res, next) {
const title = req.params.title
Sessions.find((err, sessions) => {
if (err) return console.error(err);
for (let i = 0; i < sessions.length; i++) {
if (title === sessions[i].title.toLowerCase()) {
res.render('session')
}
}
})
})

module.exports = [routes, apiRoutes];


index.js

'use strict';
const express = require('express');
const app = express();
const [routes, apiRoutes] = require('./src/routes');

require('./src/database');
require('./src/seed');

app.use('/', express.static('public'));

app.set('view engine', 'pug');
app.set('views', __dirname + '/views');

app.use('/api', apiRoutes);
app.use('/', routes);

app.listen(process.env.PORT || 8082);


service.js

const root = window.location.origin;
const title = 'session 1'

function callService(){
service(`${root}/api/sessions`)
.then(retrieveSession)
.catch(function(e) {
console.log(e)
});
}

function retrieveSession(data) {
for (let i = 0; i < data.sessions.length; i++) {
if(data.sessions[i].title.toLowerCase() === title) {
return data.sessions[i];
}
}
}

function service(url) {
return new Promise(function(res, rej) {
var httpRequest = new XMLHttpRequest();
httpRequest.open('GET', url);
httpRequest.onreadystatechange = handleResponse;
httpRequest.onerror = function(error) {
rej(error)
}
httpRequest.send();

function handleResponse() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
var data = JSON.parse(httpRequest.responseText);
res(data)
} else {
rej(this.statusText)
}
}
};
});
}

Answer

I was able to achieve the desired result by passing the data to the view via mongoose with the following snippet.

routes.get('/:title', function (req, res, next) { // Passes url param
  const title = req.params.title //stores url param in varaible
  Sessions.findOne({ 'title': title }, function (err, session) { // compares url param against my mongoose schema and queries the database for the desired object
    if (err) return handleError(err); // checks for errors
    res.render('session', {session: session}); // renders the page while passing the desired data.
  })
})
Comments