Node.js blog post add comment not working - node.js

When I add a comment to any blog post it doesn't work. This is a normal Node.js MVC controller which is linked to route:
commentBlog(req, res) {
const comment = {
comment: req.body.comment,
author: req.params.id
}
Comment.create(comment, (error, comment) => {
if (error) {
console.log(error);
} else {
Blog.findById(req.params.id, (error, blog) => {
blog.comments.push(comment);
console.log(comment);
blog.save((error, savedBlog) => {
if (error) {
console.log(error);
} else{
res.redirect('/blogs/' + blog._id);
}
})
})
}
})
};
( this is the model )
--------------------
const mongoose = require('mongoose'),
Schema = mongoose.Schema;
var commentSchema = new Schema({
author: { type: Schema.Types.ObjectId, ref: 'user' },
comment: {type: String},
created: {type: Date, default: Date.now},
blog: { type: Schema.Types.ObjectId, ref: 'blog' }
});
var Comment = mongoose.model('comment', commentSchema);
module.exports = Comment;
this is the ejs file
---------------------
<body>
<% if(blog) { %>
<form action="/blogs/<%= blog._id %>/comment" method="POST">
<textarea name="comment[text]"
rows="10" cols="50">Write something here
</textarea>
<input type="submit" value="Post comment">
</form>
<% } %>
**i don't know why it doesn't display when i add like to any post it just
don't work**

Well, you were not displaying the blog content in your ejs file. Only rendering the form. You should render the blog fields for them to display. Below is an example to show the blog title( provided there is a title field in the blog object).
<body>
<% if(blog) { %>
<h2><%= blog.title %> </h2>
<form action="/blogs/<%= blog._id %>/comment" method="POST">
<textarea name="comment[text]"
rows="10" cols="50">Write something here
</textarea>
<input type="submit" value="Post comment">
</form>
<% } %>
You can then display the other fields in your blog object using the example above.

Related

why is my form not post after using post method?

am new to nodeJS am trying to post the collection when the button is been clicked, i don't is posting because am getting an error:undefined, when i console the req.body please what am doing wrong here. is there something am not doing
Here's my code.
//create.ejs file
<form action="/blogs" method="post">
<div>
<label>Title</label>
<input name="title" type="text"/>
</div>
<div>
<label>Content header</label>
<input name="content" type="text"/>
</div>
<div>
<label>Content Body</label>
<textarea name="body"></textarea>
</div>
<div class="button">
<button>Post content</button>
</div>
</form>
//app.js file
const express = require("express")
const app = express()
const mongoose = require("mongoose")
const Schema = mongoose.Schema;
const BlogPost = new Schema({
title:{
type: String,
required: true
},
content: {
type: String,
required: true
},
body: {
type: String,
required: true
}
})
const Blog = mongoose.model("Blog", BlogPost)
module.exports = Blog;
app.post("/blogs", (req, res) => {
const blogs = new Blog({
title:req.body.title,
content: req.body.content,
body: req.body.body,
})
blogs.save()
.then(result => console.log(result))
.catch(err => console.log(err))
})
You must write
<input type="submit" name="Post content" value="Post content">
instead of this Post content
In the button element add
<button type="submit">Post content</button>
I forget to add urlencoded method.
app.use(express.urlencoded({ extended: true }))

How to get into another collections with forigen keys

I have these collections (books,book_genres,genres,books)
my book Schema is like that
var bookModel = function () {
var bookSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
author_id: {
type: mongoose.Schema.Types.ObjectId,
ref: "Author",
},
title: String,
description: String,
cover: String,
likes: Number,
});
return mongoose.model("Book", bookSchema);
};
module.exports = new bookModel();
I'm using dust templating and I'm rendering that collection data on my layout like that
{#books}
<div class="large-4 small-12 columns book">
<div class="row img-row">
<img src="{.cover}" alt="">
</div>
<div class="row">
<h3 class="small-12">{.title}</h3>
<h4 class="small-5 columns ">{.author_id}</h4>
<h4 class="small-7 columns ">{.name}</h4>
</div>
<div class="row p-row">
<p class="small-12">{.description}</p>
</div>
</div>
{/books}
my author Schema is like that
var authorModel = function () {
var authorSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: String,
});
return mongoose.model("Author", authorSchema);
};
I want to be able to reach to author name so I can render it on my layout through the author_id that I'm getting from the book Schema (for sure the id in the authors collection is the same as the author_id in the books collection)
I tried to search for some solutions but no one was using dust templating so I wasn't able to figure that out
You can use populate to resolve the Author reference:
bookModel.find({}).populate('author_id').exec();
You should then be able to access the referenced user fields with:
<h4 class="small-7 columns ">{.author_id.name}</h4>
In your case, you should change your code to:
module.exports = function (router) {
router.get('/', function (req, res) {
Book.find({})
.populate('author_id')
.exec(function (err, books) {
if (err) {
console.log(err);
}
var model = { books: books };
res.render('index', model);
});
});
};

Can't update model with mongoose schema

i'm trying to make an update functionality but it doesn't update the model :( First i make a get request to get the data from the server and populate it in form(handlebars)
so, here's the router:
router.get('/edit/:id', async (req, res) => {
const warum = await Warum.findById(req.params.id)
res.render('edit', warum);
});
router.post('/edit/:id', (req, res) => {
return Warum.findOneAndUpdate(req.params.id, { new: true }, {
title: req.body.title,
description: req.body.description,
})
.then(() => {
res.redirect('/warum');
})
.catch((err) => {
console.log(err);
});
});
that's the form:
<form method="post">
<h2>Beitrag bearbeiten</h2>
<ul class="noBullet">
<li>
<label for="title">Titel:</label>
<input type="text" name="title" value="{{title}}" />
</li>
<li>
<label for="description">Beschreibung:</label>
<textarea class="texterea" name="description">
{{description}}
</textarea>
</li>
<div>
<button class="login-button">save</button>
</div>
</ul>
</form>
and that's the schema:
const mongoose = require('mongoose')
const WarumSchema = new mongoose.Schema({
title: String,
description: String,
});
const Warum = mongoose.model('Warumschema', WarumSchema);
module.exports = Warum;
I tried to change the route from post to put, but then it says 404. After clicking the save button it just redirects me, but the result is not edited.

How to pass one Schema into another using MongoDB & Node.js

I am attempting to post comments to a blog post and have these comments as an array for each post.
I have managed to get the comments to post, but I cannot call the information from the post. The comment model has text and author in it but the comment only takes the author part of the model. When the comments show up on the post, they only show the name of the user that has written the comment. I have checked the database and comment.text isn't getting passed through at all.
Comments Create Route
router.post("/", ensureAuthenticated, (req, res) => {
Blog.findById(req.params.id, (err, blog) => {
if(err){
console.log(err);
res.redirect("/blog");
} else {
Comment.create(req.body.comment, (err, comment) => {
if(err){
req.flash("error", "Something went wrong");
console.log(err);
} else {
//add username and id to comment
comment.author.id = req.user._id;
comment.author.name = req.user.name;
comment.author.email = req.user.email;
comment.save();
//save comment
blog.comments.push(comment);
blog.save();
req.flash("success", "Successfully added comment");
res.redirect("/blog/" + blog._id);
}
});
}
});
});
Comment Schema
const mongoose = require("mongoose");
var commentSchema = new mongoose.Schema({
text: String,
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
name: String,
email: String
}
});
module.exports = mongoose.model("Comment", commentSchema);
Part of the Show Page Which Shows The Comment
<div class="card-body">
<% blog.comments.forEach(function(comment){ %>
<div class="row">
<div class="col-md-12">
<strong><%= comment.author.name %></strong>
<span class="float-right">10 days ago</span>
<p class="card-text">
<%= comment.text %>
</p>
<% if(user && comment.author.id.equals(user._id)) { %>
<a class="btn btn-warning btn-sm d-inline-block" href="/blog/<%= blog._id %>/comments/<%= comment._id%>/edit">Edit</a>
<form class="d-inline-block" action="/blog/<%= blog._id %>/comments/<%= comment._id%>?_method=DELETE" method="POST">
<button class="btn btn-danger btn-sm">Delete</button>
</form>
<% } %>
<hr>
</div>
</div>
<% }) %>
</div>
I am expecting the show page to show the text of each comment.
I was missing bodyParser. In case anyone else has this problem, https://stackoverflow.com/a/55793723/8145657 fixed it for me.

I have a schema in mongoose and i and rendering data from a schema to select the value. But now i also want the id of the selected data

Basically i have 2 sections. First is category and second is essay. The categories are added in mongoose schema and then the categories are being rendered to add essay in a specific category section. Now when i choose a specific category i also want the id of that category to store in essay schema but cant do so. Any help is appreciated
I have tried mongoose populate and schema.types.object method but aint
working for me.
// Loading essay model
require("../models/essay");
const essay = mongoose.model("essay");
// Loading category model
require("../models/category");
const category = mongoose.model("category");
// Essay processing form
router.get("/addessay", ensureAuthenticated, (req, res) => {
res.header(
"Cache-Control",
"no-cache, private, no-store, must-revalidate,max-stale=0, post-check=0,
pre-check=0"
);
category.find({}).then(category => {
res.render("addessay", {
category: category
});
});
});
// Post route to store essay in db
router.post("/essay/add", ensureAuthenticated, (req, res) => {
res.header(
"Cache-Control",
"no-cache, private, no-store, must-revalidate,max-stale=0, post-check=0, pre-check=0"
);
const newEssay = {
cat: req.body.category,
catg: req.body.categoryg,
body: req.body.body,
bodygreece: req.body.bodyg
};
new essay(newEssay).save().then(essay => {
req.flash("success_msg", "Essay Succesfully added");
res.redirect("/");
});
});
//Category Schema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// creating the schema
const categorySchema = new Schema({
category: {
type: String,
required: true
},
categorygreece: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
mongoose.model("category", categorySchema);
//Essay Schema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// creating the schema
const EssaySchema = new Schema({
cat: {
type: String,
required: true
},
catg: {
type: String,
required: true
},
body: {
type: String,
required: true
},
bodygreece: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
mongoose.model("essay", EssaySchema);
//Handlebar template (Essay adding form)
<main class="page-content my-5">
<div class="row">
<div class="col-md-6 offset-3">
<h3 class="my-5">Add Your your Essays .!</h3>
</div>
</div>
<div class="row">
<div class="col">
<form action="/essay/add" method="POST">
<div class="form-group">
<select class="categorys form-control mt-4" name="category">
{{#each category}}
<option value="{{id}}">{{category}}
</option>
{{/each}}
</select>
</div>
<div class="form-group">
<select class="categorys form-control mt-4" name="categoryg">
{{#each category}}
<option value="{{id}}">{{categorygreece}}
</option>
{{/each}}
</select>
</div>
<div class="form-group">
<h5 class="mb-3">Tell us your Essay in English!</h5>
<script src="https://cdn.ckeditor.com/4.11.4/standard/ckeditor.js"></script>
<textarea name="body" id="body-text" cols="30" rows="5" class="form-control"
placeholder="English Essay"></textarea>
<script>
CKEDITOR.replace('body');
</script>
</div>
<div class="form-group">
<h5 class="mb-3">Tell us your Essay in Greece!</h5>
<script src="https://cdn.ckeditor.com/4.11.4/standard/ckeditor.js"></script>
<textarea name="bodyg" id="body-text-2" cols="30" rows="5" class="form-control"
placeholder="Greece Essay"></textarea>
<script>
CKEDITOR.replace('bodyg');
</script>
</div>
<div class="form-group">
<input type="submit" value="SUBMIT" class="form-control btn btn-outline-dark btn-sm">
</div>
</form>
</div>
</div>
</main>
So when from options i choose a category i also want the categorys id and have to store that in essay schema.

Resources