Serving dynamic URLs with express and mongodb

21,733

If I get you right I would do that the other way around.

Short version

  1. I would get the id from the URL
  2. Then I would pull from the database the data associated with this id
  3. And use this data to build the final page.

You don't need to create a new route for each URL. An URL can contain some variable (here the id) and Express can parse the URL in order to get this variable. Then from this id you can get the data needed to build the proper page.

Long version

I assuming someone type in this URL: http://domain.com/1234.
I also assume that you have a variable titles which is a MongoDB Collection.

You can have a route defined like this:

app.get('/:id', function(req, res) {
  // Then you can use the value of the id with req.params.id
  // So you use it to get the data from your database:
  return titles.findOne({ id: req.params.id }, function (err, post) {
    if (err) { throw(err); }

    return res.render('titles', {title: post.title, url: post.URL /*, other data you need... */});
  });
});

Edit

I made some changes according to the last comments...

Share:
21,733
user1816679
Author by

user1816679

Updated on December 08, 2020

Comments

  • user1816679
    user1816679 over 3 years

    I'm building a site that has somewhat reddit-like functionality. I want user-submitted content to get its own page. Each submission is assigned a 5 character ID that I want to be in the URL for that page.

    I've got this function in the router file which renders a page called titles:

    exports.titles = function(req, res){
    i = 0
    read(function(post){
        url = post[i].URL;
        res.render('titles', {title: post[i].title, url: post[i].URL});
    });
    
    };
    

    It is served by this statement in app.js:

    app.get('/titles', home.titles); //home.js is the router file
    

    The titles page has a link with the text post.title and the URL post.URL. When a user clicks on the link (e.g. domain.com/12345) they should be taken to a page called content with the content post.body.

    How do I a)pass the URL back to my app.js file to include in an app.get, b) include the app.get function in this router file, or c) solve this in any other way?

    Edit: I do have an object 'titles' that is a mongodb collection, but it is in a different module. No reason I can't add it to the router though.

    Edit: I tried adding this to app.js to see if it would work:

    app.get('/:id', function(req, res){
      return titles.findOne({ id: req.params.id }, function (err, post) {
        if (err) throw(err); 
    
        return res.render('content', {title: post.title, content: post.body});
       });
    });
    

    Edit: I got it to work. All I did was format the title so that it would look like domain.com/titles/12345 and change app.get('/:id', to app.get('/titles/:id, ...