I am trying to figure out how to route my GET individual objects route parameter by title as opposed to ID. I know that body-parser allows for the request, but can't figure out how to modify my current route setup to allow for this to happen.
My thoughts were to change all blogpost_id to blogpost_title, but I'm running into this error.
{
"message":"Cast to ObjectId failed for value \"Data Cost Upload\" at path \"_id\"",
"name":"CastError",
"type":"ObjectId",
"value":"Data Cost Upload",
"path":"_id"
}
routes.js:
//Route for individual blogs
router.route('/blog/:blogpost_id')
// START GET method blog by ID
.get(function(req, res) {
Blogpost.findById(req.params.blogpost_id, function(err, blogpost) {
if (err)
res.send(err);
//res.json(blogpost);
res.render('pages/blogpost', {
blogpost: blogpost
});
});
}) // END GET method blog by ID
// START PUT method
.put(function(req, res) {
Blogpost.findById(req.params.blogpost_id, function(err, blogpost) {
if (err)
res.send(err);
blogpost.title = req.body.title; // update the blog title
blogpost.author = req.body.author; // update the author name
blogpost.tagline = req.body.tagline; // update the tagline
blogpost.content = req.body.content; // update the blog content
blogpost.category = req.body.category; // update the category
blogpost.tags = req.body.tags; //update the tags
blogpost.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Blog updated.' });
});
});
}) // END PUT method
// START DELETE method
.delete(function(req, res) {
Blogpost.remove({
_id: req.params.blogpost_id
}, function(err, bear) {
if (err)
res.send(err);
res.json({ message: 'Successfully deleted' });
});
});
How I'm linking through to each individual object:
<div class="blog-content">
<% blogpost.forEach(function(blogpost) { %>
<tr>
<td><h2><a href="#" class="blog-title"><%= blogpost.title %></a></h2></td>
<td><h3><%= blogpost.date %></h3></td>
<td><h3 class="blog-category"><%= blogpost.category %></h3></td>
<td><h3 class="blog-tagline"><i><%= blogpost.tagline %></i></h3></td>
<td><p><%=: blogpost.content | truncate:800 | append:'...' %></p></td>
<td><a href="/blog/<%= blogpost.title %>" class="blog-read-more">Read More</a></td>
</tr>
<% }); %>
</div>
Result URL from clicking on "Read More": http://localhost:8080/blog/Data%20Cost%20Upload
when you get http://localhost:8080/blog/Data%20Cost%20Upload
route.get handler called with req.params.blogpost_id = "Data Cost Upload".
Blogs.findById expects first argument to be mongoose.Types.ObjectId, but req.params.blogpost_id is a string
If you want to get your blogpost by title, use
function getSearchCriteria(params) {
return {
title: params.blogpost_title
};
}
function getBlogpostUpdate(body) {
return {
title: body.title,
author: body.author,
tagline: body.tagline,
content: body.content,
category: body.category,
tags: body.tags
};
}
var blogpostsRoute = router.route('/blog/:blogpost_title');
// to manipulate your route params, use router.param
router.param('blogpost_title', function (req, res, next, blogpost_title) {
req.params.blogpost_title = blogpost_title.toLowerCase();
next();
});
blogpostsRoute
.get(function (req, res) {
var searchCriteria = getSearchCriteria(req.params);
Blogpost.findOne(searchCriteria, function (err, blogpost) {
if (err)
res.send(err);
res.render('pages/blogpost', {
blogpost: blogpost
})
})
})
.put(function (req, res) {
var searchCriteria = getSearchCriteria(req.params);
var updated = getBlogpostUpdate(req.body)
Blogpost.findOneAndUpdate(searchCriteria, updated, function (err, updated) {
if (err)
res.send(err);
res.json({ message: 'Blog updated.' });
});
})
.delete(function (req, res) {
var searchCriteria = getSearchCriteria(req.params);
Blogpost.findOneAndRemove(searchCriteria, function (err, removed) {
if (err)
res.send(err);
res.json({ message: 'Successfully deleted' });
});
});