3

I have this menu on every page in my Node website:

enter image description here

I populate it on each request using some custom middleware:

app.use(function(req, res, next) {
  // find the 9 most popular technologies to show in the 'technologies' menu 
  // drop-down. this data is needed on every page, hence the middleware.
  var query = 
    'select \
       t.technologyName, \
       count(*) as count \
     from technologies t \
     join technology_video_map m \
       on m.technologyName = t.technologyName \
     where t.technologyName in ( \
       select technologyName \
       from technology_video_map m \
       join videos v \
         on m.videoId = v.videoId \
       where v.approved = 1) \
     group by t.technologyName \
     order by count desc, t.technologyName desc \
     limit 9';
  connection.query(query, function(err, technologies) {
    if (technologies.length === 9) {
      // 'Other' is a special technology
      technologies.push({ technologyName:'Other' });
    }
    res.locals.technologies = technologies;
    next();
  });
});

However, I have routes which return Json that, when invoked, invoke this middle-ware. This is inducing superfluous database calls. How can I only invoke this middle-ware when a view is returned?

// yes, invoke the middleware here!
router.get('/about', function(req, res) {
  res.render('about');
});

// no, don't invoke the middleware here, we don't have a view!
router.get('/autocomplete', function(req, res) {
  res.send({ options: new [] });
});

(I am also keen to cache this information, but I will ask another question about how to cache using node-mysql.)

Angular noob
  • 437
  • 4
  • 11

1 Answers1

0

You can tell the router to only invoke the middleware on specific routes as described in the Express documentation here

// will be invoked on every call to /about
router.use('/about', function(req, res, next) {
  console.log('I\m such a middleware');
  next();
});

// will be invoked on every call to /json/...
router.use('/json/:somejson', function(req, res, next) {
  console.log('json comin..');
  next();
});

// yes, invoke the middleware here!
router.get('/about', function(req, res) {
  res.render('about');
});

// no, don't invoke the middleware here, we don't have a view!
router.get('/json/autocomplete', function(req, res) {
  res.send({ options: new [] });
});

I'd go with segmenting my routes and calling the db middleware only on calls to `/view/..', for example..

VF_
  • 2,627
  • 17
  • 17