I have a blog and when I want to edit a post the URL becomes "/blog/:title/edit" and when I change the title of the blog and hit submit the URL should become "/blog/:title" and take me to the updated post. But this doesn't happen because when the title is updated in database the ":title" in the URL will not be updated. So my problem is when I click on the submit button the URL should change from "/blog/:title/edit" to "/blog/:newTitle"
Here is the Express code:
var express = require("express"),
methodOverride = require("method-override"),
bodyParser = require("body-parser"),
mongoose = require("mongoose"),
app = express();
mongoose.connect("mongodb://localhost:27017/blog", {useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false});
app.use(bodyParser.urlencoded({extended: true}));
app.set("view engine", "ejs");
app.use(express.static("public"));
app.use(methodOverride("_method"));
var blogSchema = new mongoose.Schema({
title: String,
image: String,
body: String,
created: {type: Date, default: Date.now}
})
var Blog = mongoose.model("Blog", blogSchema);
app.get("/", function(req, res){
res.redirect("/blog");
})
app.get("/blog", function(req, res){
Blog.find({}, function(err, blog){
if(err){
console.log(err);
}
else{
res.render("index",{blog: blog});
}
})
})
app.get("/blog/new", function(req, res){
res.render("new");
})
app.post("/blog", function(req, res){
Blog.create(req.body.blog, function(err, newBlog){
if(err){
res.render("new");
}
else{
res.redirect("/blog");
}
})
})
app.get("/blog/:title", function(req, res){
Blog.findOne({title: req.params.title}, function(err, foundBlog){
if(err){
res.redirect("/blog");
}
else{
res.render("show", {blog: foundBlog});
}
})
})
app.get("/blog/:title/edit", function(req, res){
Blog.findOne({title: req.params.title}, function(err, foundBlog){
if(err){
res.redirect("/blog");
}
else{
res.render("edit", {blog: foundBlog});
}
})
})
app.put("/blog/:title", function(req, res){
Blog.findOneAndUpdate({title: req.params.title}, req.body.blog, function(err, updatedBlog){
if(err){
res.redirect("/blog");
}
else{
res.redirect("/blog/"+req.params.title);
}
})
})
app.listen(3000, function(){
console.log("server listening at port 3000");
})
And here is the edit.ejs code:
<%- include("partials/header") %>
<div class="ui main text container segment">
<div class="ui huge header">Edit <%= blog.title %></div>
<form class="ui form" action="/blog/<%= blog.title %>?_method=PUT" method="POST">
<div class="field">
<label>Title</label>
<input type="text" name="blog[title]" value="<%= blog.title %>">
</div>
<div class="field">
<label>Image</label>
<input type="text" name="blog[image]" value="<%= blog.image %>">
</div>
<div class="field">
<label>Blog Content</label>
<textarea name="blog[body]"><%= blog.body %></textarea>
</div>
<input class="ui violet big inverted button" type="submit">
</form>
</div>
<%- include("partials/footer") %>
Top comments (10)
Maybe the error is here:
When you update the blog post, you are looking for the title, but if the title is different from the original, it won't find it and create a new entry on your database. I recommend that you use the id of the post to make sure that you are referring to the same entry.
If I use ID then I can't get the title on the URL. So is there any way to do it without the ID?
Can I store the updated title in a variable and use it in the URL?
As I understood, you can update the document on the database right? I'm assuming that as a yes 😅 So the problem, for what I can tell, is that you reach the PUT endpoint and use the params to search the old title with "req.params.title".
When you finish updating the database the old title does not exist anymore, but you keep using the same URL that contains the old title to redirect the page.
Since your database cant find the old title you can not be redirected to the updated blog 😅, I suggest you change the "req.params.title" on your redirect call to "req.body.blog.title" since the blog object contains the new title. Hope I could help you 😄
OMG!! Thank you. I thought of this at first but forgot later. Now I'm getting the title in the URL!!😁😁
Yes you could do that and use it in the put. But it's not a great practice using a variable that change as a parameter in your endpoint.
You might want to consider redirecting the user to the new and updated link, but a better solution would be to use constant IDs in the URL, or any other day that will never change.
Thank you!!😊 But I don't want to use IDs. I want the title to show title in the URL as it looks good.
Would it possible to use IDs internally during the search and use titles after?
Ya that is what I'm looking for!!
u can just pass on the put else redirect the updatedBlog.title