0

So I'm trying to make a simple page handler for a website (My First NodeJS Project) and struggling to get my head around how to get a MySQL Query to run each time and store the returned data in a variable to be used throughout the application. (I should note I'm using ExpressJS)

Currently in my app.js file I have the following, which seems to be doing it's job at executing for each page load

app.use(pageHandler);

Inside the pageHandler module, I have the following which queries the database based on the URL of the page.

var pageHandler= app.use(function (req, res, next) {
    console.log('Trying to find details for page: ' + url.parse(req.url).pathname);
    db.query("SELECT * FROM `pages` WHERE page_url = ?", [url.parse(req.url).pathname], function(err, result) {
        res.send(result);
    });
});

module.exports = pageHandler;

This does infact print, the successful results on the page, but I'm wanting to store them in a variable wihch I can use throughout the application to get for example the title of the page and whatnot. Currently returns the following from database.

[  
   {  
      "id":1,
      "page_url":"/",
      "title":"Home",
      "meta_title":"First Node Project",
      "meta_description":"Placeholder",
      "meta_keywords":"nodejs, keywords, etc",
      "parent_id":0,
      "position":0,
      "template":"home",
      "content":"Lipsum..."
   }
]

1 Answer 1

2

For Express apps, you can use res.locals for that:

var pageHandler= function (req, res, next) {
    console.log('Trying to find details for page: ' + url.parse(req.url).pathname);
    db.query("SELECT * FROM `pages` WHERE page_url = ?", [url.parse(req.url).pathname], function(err, result) {
        res.locals.page = result;
        next();
    });
};

module.exports = pageHandler;

This will expose a variable called page to your templates, and from other request handlers you can access it as res.locals.page.

EDIT: from what I understand from your comments, you want to use the above pageHandler middleware to dynamically handle page requests. Basically, when a request arrives, it will perform a database lookup against the path name and use the results to render a template.

That's perfectly acceptable, and you can use a normal middleware for that, but since you probably want to limit those requests to GET only, here's a more specific implementation:

let pageHandler = function(req, res, next) {
  console.log('Trying to find details for page:', req.path);
  db.query("SELECT * FROM `pages` WHERE page_url = ?", [ req.path ], function(err, result) {
    // Pass errors to Express so it can handle them.
    if (err) return next(err);

    // If there was no matching page, pass the request along.
    if (result.length === 0) return next();

    // Render the template with the page data.
    res.render(YOUR_TEMPLATE, { page : result[0] });
  });
});

// To use:
app.get('*', pageHandler);

It also implements proper error handling, and if there wasn't a matching database document for that particular path, it will pass the request to other potential route handlers. And it uses req.path instead of parsing req.url.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks a lot for this, really helps - I do have a couple questions though if you don't mind? I have things printing out in templates and whatnot just fine, but is it possible to use this to actually define the routes in app.js? So I don't have to hard-code each of the routes for all the pages - it can pull them all through from the database based on the page_url and template fields?
Sure, but how is that different from your original code? It sounds like you want to look up the path name in the database, and render a template based on what the database returns, which seems to me is almost exactly what your original code does (although instead of res.send(result) you'd call res.render() on a template file).
Yeah that's what I want to do, but from what I currently understand - for each page on your site you need to do something like the following? var home = require('./routes/index'); app.use('/', home); So how would you go about implementing dynamic routes / uses in the app file? Or am I over-complicating the process?
Thanks a a lot! This is exactly what I was looking to achieve, greatly appreciated!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.