How do you make a Node JS Route by Slug not by ID?

Issue

I am working on a NodeJS blog that works on the MEAN stack (using Express router as well). I do have slugs saved in my MongoDB as strings as well. The end goal I am trying to get is if can call routes using :slug instead of :id

The current working route that gets my resources by id is:

router.get("/resources/:id", async (req, res) => {
    let foundResource = await Resources.findById(req.params.id);
        var metaTitle = foundResource.title;
        var metaDescription = foundResource.description;
        var metaKeywords = foundResource.keywords;
        var metaPath = foundResource.image;
    if (foundResource) {
        let allResources = await Resources.find({});
        res.render("insider/show", { Resources: allResources, resource: foundResource, metaTitle: metaTitle, metaDescription: metaDescription, metaKeywords:metaKeywords, metaPath:metaPath, page_name:'insider'});
    }

});

I would like it to be something similar like this:

router.get("/resources/:slug", async (req, res) => {
    let foundResource = await Resources.find(req.params.slug);
        var metaTitle = foundResource.title;
        var metaDescription = foundResource.description;
        var metaKeywords = foundResource.keywords;
        var metaPath = foundResource.image;
    if (foundResource) {
        let allResources = await Resources.find({});
        res.render("insider/show", { Resources: allResources, resource: foundResource, metaTitle: metaTitle, metaDescription: metaDescription, metaKeywords:metaKeywords, metaPath:metaPath, page_name:'insider'});
    }
});

The model that drives these routes is as follows:

// schema setup
var mongoose = require("mongoose");

var resourceSchema = new mongoose.Schema({
    title: String,  
    image: String,
    url: String,
    resourceDetails: String,
    price: String,
    category: String,
    value: String,
    excerpt: String,
    slug: String,
    create: {type: Date, default: Date.now},
    author: {
      id: {
         type: mongoose.Schema.Types.ObjectId,
         ref: "User"
      },
      username: String
   },
});

module.exports = mongoose.model("Resources", resourceSchema);

Every attempt I have made either gives me a cast error (can’t find the ID) or loads the template page without any data in it.

Thanks in advance for your help!

Solution

If you were using findById before, you’d want to replace that with findOne – and indicate the field you are looking for.

So replace

let foundResource = await Resources.find(req.params.slug);

With

let foundResource = await Resources.findOne({slug: req.params.slug});

As a side note – know that mongo automatically indexes _id, so if you are changing it to look up slug, you’ll likely want to index that field for performance.

Answered By – AdamExchange

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published