0

I am using Node.js v ~4.

I am trying to build routes by using objects from database. This is my logic:

  for (page of pages) {
    app.get(`/${page.path}`, (req, res)=> {
      res.render('test', {
        page:page,
      })
    })
  }

However , no matter which url I access, I always get contents from last object in database.

So urls work, but code inside app.get() callback function is not working properly. For example page variable is invalid, last object is displayed, rather than one matching path. If I would add this code:

console.log(req.url);
console.log(page.path);

as first line inside callback function, I would get next output:

Hitting first url:

/test01
test03

Hitting second url:

/test02
test03

Is there more convenient approach for dynamic routes and pages?

Kunok
  • 8,089
  • 8
  • 48
  • 89
  • Possible duplicate of [JavaScript closure inside loops – simple practical example](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Andy Ray Nov 18 '16 at 17:22

2 Answers2

1

You need an to use let on your variable being iterated over to preserve the scope - else it'll always bind the route to the last item being iterated over:

Since let isn't supported in node, use an IIFE:

for (page of pages) {
    (function(p) {
        app.get(`/${p.path}`, (req, res)=> {
            res.render('test', {
                page:p,
            })
        })
    })(page)
}
tymeJV
  • 103,943
  • 14
  • 161
  • 157
1

This works for me:

router.get('/:page', function (req, res) {
    var page = req.params.page;
    if (pages.indexOf(page) === -1) res.redirect('/');
    else res.render('index', {title: page});
});