node.js POST empty req.body - node.js

I'm having trouble when I store data to MySQL database. I get a return in console blank.like this {}
here's route code :::app.post('/create', employeeController.create);
this is my controller code
exports.create = function(req, res) {
console.log((req.body));
const new_employee = new Employee(req.body);
//handles null error
if(req.body.constructor === Object && Object.keys(req.body).length === 0){
res.status(400).send({ error:true, message: 'Please provide all required field' });
}else{
Employee.create(new_employee, function(err, employee) {
if (err)
res.send(err);
res.json({error:false,message:"Employee added successfully!",data:employee});
});
}
};
this is my model code:
var db = require('../database');
//Employee object create
var Employee = function(employee){
this.name = employee.name;
this.email = employee.email;
this.position = employee.position;
};
Employee.create = function (newEmp, result) {
db.query("INSERT INTO employee set ?", newEmp, function (err, res) {
if(err) {
console.log("error: ", err);
result(err, null);
}
else{
console.log(res.insertId);
result(null, res.insertId);
}
});
};
module.exports= Employee;
my view code:
<form action="/create" enctype="multipart/form-data" method="POST">
<div class="row">
<div class="col-md-6">
<label>Name</label>
<input name="name" type="text" class="form-control" required>
</div>
<div class="col-md-6">
<label>Email</label>
<input name="email" type="email" class="form-control" required>
</div>
</div>
<div class="row">
<div class="col-md-6">
<label for="exampleFormControlTextarea1" class="form-label">Position</label>
<input name="position" type="text" class="form-control" required>
</div>
</div>
<button type="submit" class="btn btn-primary">Save</button>
<button type="submit" class="btn btn-primary">Cancel</button>
<br><br>
</form>
Im getting {} in log it means req.body is getting blank.
i have tried in app.js
app.use(bodyParser.json());
app.use(express.urlencoded({limit: '100mb',extended: false }));
but it's not working

Add app.use(bodyParser.urlencoded({ extended: false })) before your app.use(bodyParser.json());, and remove app.use(express.urlencoded({limit: '100mb',extended: false }));.
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json());
Then remove enctype="multipart/form-data" in the form. Because your form only have text input, so you could remove it. And bodyParser doesn't support multipart/form-data.

Related

I keep getting validator errors after submitting my form in Node.js using EJS templating engine

The code works well and perfectly when i use Postman to make the requests. But whenever I send the same request from the frontend I get this error.
Result {
formatter: [Function: formatter],
errors: [
{
value: undefined,
msg: 'Please enter your name',
param: 'name',
location: 'body'
},
{
value: '',
msg: 'Please enter a valid Email',
param: 'email',
location: 'body'
},
{
value: undefined,
msg: 'Please enter a password with 6 or more characters',
param: 'password',
location: 'body'
}
]
}
Here is my signup.ejs file.
<!doctype html>
<html lang="en">
<%- include('./partials/header.ejs')%>
<%- include('./partials/navbar.ejs')%>
<body>
<section class="form my-4 mx-5">
<div class="container">
<div class="row no-gutter">
<div class="col-lg-5">
<img src="/images/joyce-busola-Nnv0DHFG1Ds-unsplash.jpg" class="img-fluid">
</div>
<div class="col-lg-7 px-5 pt-5">
<h1 class="font-weight-bold py-3">Queue's</h1>
<h4>Register your new Account</h4>
<form action="/user/register" method="POST">
<div class="form-row">
<div class="col-lg-7">
<input type="text" id="name" class="form-control my-3 p-3" placeholder="your name">
</div>
</div>
<div class="form-row">
<div class="col-lg-7">
<input type="email" id="email" class="form-control my-3 p-3" placeholder="email address">
</div>
</div>
<div class="form-row">
<div class="col-lg-7 input-group">
<input type="password" class="form-control my-3 p-3" id="password" placeholder="password">
<div class="input-group-addon my-3 p-3">
</a><i class="bi bi-eye-slash" id="togglePassword"></i>
</div>
</div>
</div>
<div class="form-row">
<div class="col-lg-7">
<button type="submit" class="btn1 mt-3 mb-5">Register</button>
</div>
</div>
forgot password
<p>Already have an acount? Login here</p>
</form>
</div>
</div>
</div>
</section>
<%- include('./partials/footer.ejs')%>
</body>
</html>
Here is a copy of my signup controller object.
require('dotenv').config();
const jwt = require('jsonwebtoken');
const User = require('../models/User');
const { createToken } = require('../middleware/auth_middleware');
const maxAge = 36000;
module.exports.register_post = async (req, res) => {
const { name, email, password } = req.body;
// Searching if User already exists
try {
let user = await User.findOne({ email });
if(user) return res.status(400).json({ errors : [{ msg: "User already exists"}],});
// Create User Object
user = new User({ name, email, password });
// Saving new User
await user.save();
// Creating User token with JWT
let payLoad = user._id;
const prize = createToken(payLoad);
res.cookie('jwt', prize, {
httpOnly: true,
maxAge : maxAge * 1000
});
res.status(201).json({
msg: `${user.email} successfully registered`,
name: user.name,
email: user.email});
console.log(user, prize);
}
catch (error) {
console.log(error.message);
res.status(500).send('Server error')
};
}
I made a middleware to handle validations with express-validator. Here is the validator file.
require('dotenv').config()
const { check, validationResult } = require('express-validator');
const jwt = require('jsonwebtoken');
const maxAge = 36000;
const secret = process.env.JWT_SECRET;
const authValidator = () => {
return [
check('name', 'Please enter your name').not().isEmpty(),
check('email', 'Please enter a valid Email').trim().isEmail(),
check('password', 'Please enter a password with 6 or more characters').isLength({min:6})
]};
const validateError = (req, res, next) => {
const errors = validationResult(req);
if(errors.isEmpty()) {
return next()
}
const extractedErrors = [];
errors.array().map(err => extractedErrors.push({ [err.param]: err.msg }))
console.log(errors);
return res.status(400).json({ errors: extractedErrors })
}
Here is the signup router file
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');
const { authValidator, validateError } = require('../middleware/auth_middleware');
router.get('/login', userController.login_get );
router.post('/login', userController.login_post );
router.get('/register', userController.register_get );
router.post('/register', authValidator(), validateError, userController.register_post );
module.exports = router;
Your input fields lack the name field. That's why the input data is not found in the body of the request.
for example for the email field:
<div class="form-row">
<div class="col-lg-7">
<input type="email" name="email" id="email" class="form-control my-3 p-3" placeholder="email address">
</div>
</div>

Why am I getting a 400 bad request error when submitting a form that I added inputs to?

Background: I have a node/express based web application that is basically a rating/database site for campgrounds. You can view the current working version here: https://radiant-eyrie-76078.herokuapp.com and the github here: https://github.com/HashSlingSlash/YelpCamp. I've just completed attempting to add user profiles by updating the signup form to include more information and adding a show page for each user. Now whenever I click the signup button (or send a post request to /register using postman) I get a 400 Bad Request error. If I then go to the home page I can sign in as the user that I attempted to register so the user is getting registered despite the bad request error. I have tried clearing my cache and browsing history and using other browsers, but it still won't work. I even tried removing all the changes I made to the form to make it just username and password again and it still did not work. I have tried fixing this and debugging for hours and I cannot understand what could be happening.
Here is my register page:
<%- include("./partials/header") %>
<div class="row">
<h1 class="login-header">Sign Up</h1>
<div class="login-form">
<form action="/register" method="POST">
<div class="form-group">
<label for="username">Username</label>
<input class="form-control" type="text" name="newUser[username]" placeholder="username" id="username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input class="form-control" type="password" name="password" placeholder="password" id="password">
</div>
<div class="form-group">
<label for="firstName">First Name</label>
<input class="form-control" type="text" name="newUser[firstName]" placeholder="First Name" id="firstName">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input class="form-control" type="text" name="newUser[lastName]" placeholder="Last Name" id="lastName">
</div>
<div class="form-group">
<label for="email">Email</label>
<input class="form-control" type="email" name="newUser[email]" placeholder="email#mail.com" id="email">
</div>
<div class="form-group">
<label for="avatar">Avatar</label>
<input class="form-control" type="text" name="newUser[avatar]" placeholder="avatar url" id="avatar">
</div>
<div class="form-group">
<label for="admin">Admin Key (Enter admin key here if you've been given one)</label>
<input class="form-control" type="text" name="adminKey" placeholder="********" id="admin">
</div>
<div class="form-group">
<button class="btn btn-lg btn-primary btn-block">Sign Up!</button>
</div>
</form>
Go Back
</div>
</div>
<%- include("./partials/footer") %>
Here are my index routes:
const express = require("express");
const router = express.Router();
const passport = require("passport");
const User = require("../models/user");
const Campground = require("../models/campground");
//root route
router.get("/", (req, res) =>{
res.render("landing");
});
//show register form
router.get("/register", (req, res) =>{
res.render("register", {page: "register"});
});
//handle sign up logic
router.post("/register", (req, res) =>{
const newUser = new User(req.body.newUser);
if(req.body.adminKey === "secret"){
newUser.isAdmin = true;
}
User.register(newUser, req.body.password, (err, user) =>{
if(err){
return res.render("register", {"error": err.message});
}
passport.authenticate("local")(req, res, () =>{
req.flash("success", "Welcome to YelpCamp " + user.username);
res.redirect("/campgrounds");
});
});
});
//login form
router.get("/login", (req, res) =>{
res.render("login", {page: "login"});
});
//login logic
router.post("/login",
passport.authenticate("local",
{
failureRedirect: "/login",
failureFlash: true
}), (req, res) =>{
req.flash("success", "Welcome back " + req.user.username);
res.redirect("/campgrounds");
});
//logout
router.get("/logout", (req, res) =>{
req.logOut();
req.flash("success", "Logged you out!");
res.redirect("/campgrounds");
});
//user profile
router.get("/user/:id", (req, res) =>{
User.findById(req.params.id, (err, foundUser) =>{
if(err){
req.flash("error", "Something went wrong");
return res.redirect("back");
}
Campground.find().where("author.id").equals(foundUser._id).exec((err, campgrounds) =>{
if(err){
req.flash("error", "Something went wrong");
return res.redirect("back");
}
res.render("users/show", {user: foundUser, campgrounds: campgrounds});
});
});
});
module.exports = router;
Here is my User schema:
const mongoose = require("mongoose");
const passportLocalMongoose = require("passport-local-mongoose");
const UserSchema = new mongoose.Schema({
username: String,
password: String,
firstName: String,
lastName: String,
email: String,
avatar: String,
isAdmin: {type: Boolean, default: false}
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
I've tried fixing this for hours and would appreciate any help!
I finally figured out the issue. I had to change the name attribute on the form inputs to just username, password, email, etc. I believe passport local mongoose expects to receive the data according to those key value pairs specifically, although I am unsure as to the exact reason why this is necessary since I end up giving the data as an object either way. In case anyone wants to see it here is my updated and working code:
Register form:
<%- include("./partials/header") %>
<div class="row">
<h1 class="login-header">Sign Up</h1>
<div class="login-form">
<form action="/register" method="POST">
<div class="form-group">
<label for="username">Username</label>
<input class="form-control" type="text" name="username" placeholder="username" id="username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input class="form-control" type="password" name="password" placeholder="password" id="password">
</div>
<div class="form-group">
<label for="firstName">First Name</label>
<input class="form-control" type="text" name="firstName" placeholder="First Name" id="firstName">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input class="form-control" type="text" name="lastName" placeholder="Last Name" id="lastName">
</div>
<div class="form-group">
<label for="email">Email</label>
<input class="form-control" type="email" name="email" placeholder="email#mail.com" id="email">
</div>
<div class="form-group">
<label for="avatar">Avatar</label>
<input class="form-control" type="text" name="avatar" placeholder="avatar url" id="avatar">
</div>
<div class="form-group">
<label for="admin">Admin Key (Enter admin key here if you've been given one)</label>
<input class="form-control" type="text" name="adminKey" placeholder="********" id="admin">
</div>
<div class="form-group">
<button class="btn btn-lg btn-primary btn-block">Sign Up!</button>
</div>
</form>
Go Back
</div>
</div>
<%- include("./partials/footer") %>
Route:
//handle sign up logic
router.post("/register", (req, res) =>{
const newUser = new User({
username: req.body.username,
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
avatar: req.body.avatar
});
if(req.body.adminKey === "secret"){
newUser.isAdmin = true;
}
User.register(newUser, req.body.password, (err, user) =>{
if(err){
return res.render("register", {"error": err.message});
}
passport.authenticate("local")(req, res, () =>{
req.flash("success", "Welcome to YelpCamp " + user.username);
res.redirect("/campgrounds");
});
});
});

Form validation with flash messages in express js

I am trying to validate a form in express js before i post it onto the mongodb which i am using as a backend. My user.js for registration page looks something like this -
router.post('/register', (req, res) => {
userreg.register(
// eslint-disable-next-line new-cap
new userreg({
firstname: req.body.firstname,
lastname: req.body.lastname,
username: req.body.email,
usn: req.body.usn, // validate so that no space is taken or else request modal wont work
course: req.body.course,
}),
req.body.password,
(err) => {
if (err) {
console.log(err);
res.render('register', { user: 'error' });
} else {
console.log('no error');
res.render('submit-success', { username: req.body.firstname });
}
}
);
});
and my register.ejs looks something like this -
<form class="user" action = '/users/register' method="POST">
<div class="form-group row">
<div class="col-sm-6 mb-3 mb-sm-0">
<input type="text" class="form-control form-control-user" id="exampleFirstName" name="firstname" placeholder="First Name">
</div>
<div class="col-sm-6">
<input type="text" class="form-control form-control-user" id="exampleLastName" name="lastname" placeholder="Last Name">
</div>
</div>
<div class="form-group">
<input type="email" class="form-control form-control-user" id="exampleInputEmail" name="email" placeholder="Email Address">
</div>
<div class="form-group">
<input type="text" class="form-control form-control-user" id="exampleInputUSN" name="usn" placeholder="USN">
</div>
<div class="form-group">
<select class=" form-control selectpicker" name="course">
<optgroup label="Course"></optgroup>
<option selected hidden disabled>Course</option>
<option value="mca">Computer Applications</option>
<option value="mba">Business Administration</option>
</optgroup>
</select>
</div>
<div class="form-group">
<input type="password" class="form-control form-control-user" id="exampleInputPassword" name="password" placeholder="Password">
</div>
<div class="text-center">
<input type="submit" class = "btn btn-primary btn-user" value="Register">
</div>
</form>
By going through many sources on the internet(since i'm very very new to express js and im doing it as a part of my college project and since i can't consult any teachers for assistance during lockdown times) , I got to know that the validation part has to be implemented in user.js. Please help me with the code for validation and also displaying flash messages if field empty for atleast one field so that i can have a start atleast.
Thank you in advance
EDIT :
I Used the express-validator and ended up with the following changes -
var flash = require('connect-flash');
var app = express();
app.configure(function () {
app.use(express.cookieParser('keyboard cat'));
app.use(express.session({ cookie: { maxAge: 60000 } }));
app.use(flash());
});
app.get('/flash', function (req, res) {
// Set a flash message by passing the key, followed by the value, to
req.flash().
req.flash('info', 'There is an Error!')
res.redirect('/');
});
app.get('/', function (req, res) {
// Get an array of flash messages by passing the key to req.flash()
res.render('index', { messages: req.flash('info') });
});
const { check, validationResult } = require('express-validator');
router.post('/register', [
check('firstname', 'Please enter your first
name').exists().trim().escape().not().isEmpty(),
check('lastname', 'Please enter your last
name').exists().trim().not().isEmpty(),
check('username', 'Please enter an
email').exists().trim().not().isEmpty(),
check('usn', 'Please enter USN').exists().trim().not().isEmpty(),
check('course', 'Please enter Course').exists().trim().not().isEmpty(),
check('password', 'Please enter
password').exists().trim().not().isEmpty(),
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
req.flash('message', `${errors}`);
res.redirect('/users/register');
} else {
userreg.register(
// eslint-disable-next-line new-cap
new userreg({
firstname: req.body.firstname,
lastname: req.body.lastname,
username: req.body.email,
usn: req.body.usn, // validate so that no space is taken or else
request modal wont work
course: req.body.course,
})),
res.render('submit-success', { username: req.body.firstname });
}
}
);
And as a result , the if (!errors.isEmpty()) is being invoked but there is no flash message being displayed. Am i missing something else ?
I am assuming you are using connect-flash.
const { check, validationResult } = require('express-validator');
router.post('/register', [
check('firstname', 'Please enter your first name').exists().trim().escape().not().isEmpty(),
check('lastname', 'Please enter your last name').exists().trim().not().isEmpty(),
check('email', 'Please enter an email').exists().trim().not().isEmpty(),
// ...
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
req.flash('message', `${errors}`);
res.redirect('register');
}
else {
// your code here!
}
});
You might want to consider creating middleware to handle validation errors, to make your code cleaner.

Unable to update MongoDB from edit profile page

I am trying to update my particular user database on edit profile page.But I don't know where I am going wrong in it.
{{!--editProfile.hbs--}}
<link rel="stylesheet" href="myprofile.css">
<title>Edit Profile Page</title>
<body>
<div class="container">
<h1>Edit Profile</h1>
<hr>
<div class="row">
<!-- left column -->
<div class="col-md-3">
<div class="text-center">
<img src="//placehold.it/100" class="avatar img-circle" alt="avatar">
<h6>Upload a different photo...</h6>
<input type="file" class="form-control">
</div>
</div>
<!-- edit form column -->
<div class="col-md-9 personal-info">
<h3>Personal info:</h3>
<form class="form-horizontal" role="form" action="/addDB" method="POST">
<div class="form-group">
<label class="col-lg-3 control-label" for="username">Username:</label>
<div class="col-lg-8">
<input class="form-control " type="text" id="username" name="username"placeholder="Username">
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Email:</label>
<div class="col-lg-8">
<input class="form-control " type="text" placeholder="Email" name="email">
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Password:</label>
<div class="col-md-8">
<input class="form-control " type="password" placeholder="Password"name="password">
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label" for="phone">Phone:</label>
<div class="col-md-8">
<input class="form-control " type="text" id="phone" placeholder="Phone"name="phone">
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label"></label>
<div class="col-md-8">
button class="btn btn-primary" type="submit">Save Changes</button>
</div>
</div>
</form>
</div>
</div>
</div>
<hr>
</body>
</html>
//index.js
var express=require('express');
var app=express();
var session=require('express-session');
var mongoClient=require("mongodb").MongoClient;
var db;
mongoClient.connect("mongodb://localhost:27017",function(err,client){
if (err) throw err;
db=client.db("myDBS");
});
app.use(
session({secret: "Express session secret"}));
app.use(express.urlencoded({ extended:false}));
app.set('view engine', 'hbs');
app.use(express.static(__dirname + '/public'));
app.get("/", function(req, res){
res.sendFile(__dirname + "/login.html");});
//For Inserting new User in DB
app.get('/addS',function(req,res){
res.render('addNewUsers');
});
app.post("/add",function(req,res){
db.collection("users").insert(req.body);
console.log("Insert successfully");
res.render("myprofile");
});
//for updating DB
app.post('/addDB', function(req, res, next) {
var data = {
username: req.body.username,
email: req.body.email,
password: req.body.password,
phone:req.body.phone
};
// var id = req.body.id;
mongoClient.connect("mongodb://localhost:27017", function(err, db) {
db.collection('users').updateOne({$set: data}, function(err, result) {
console.log('User updated');
db.close();
});
});
});
app.get("/edit",function(req,res){
res.render("editProfile");
});
app.get("/dmyprofile",function(req,res){
res.render(307,"/myprofile");
});
app.post("/myprofile",function(req,res){
db.collection("users").find().toArray(function(err,result){
if (err) throw err;
for(var i=0;i<result.length;i++){
if(req.body.email==result[i].email &&
req.body.password==result[i].password)
{
req.session.loggedIn=true;
}
}
res.redirect("/user");
});
});
app.get("/user",function(req,res){
if(req.session.loggedIn==true){
res.render("myprofile");
}else{
res.redirect("/");
}
});
app.get("/logout",function(req,res){
req.session.destroy();
res.redirect("/");
});
app.listen(3355,function(){
console.log("Listening on 3355");
});
when I am clicking on save changes it is showing me db.collection not a function. Though my insert route is working fine but update part is not working.
All other routes are working fine. But this update part is throwing error.
The problem here is the way you are connecting to MongoDB.
To have direct access to the collections after connecting to Mongo you must have the database name in the connection string, like in the code below:
mongoClient.connect("mongodb://localhost:27017/MyDBS", function(err, db) {
db.collection('users').updateOne({$set: data});
});
The other way to get access to the collections is connecting to Mongo and choosing the which database to use right after, like you did upper in your code:
mongoClient.connect("mongodb://localhost:27017",function(err,client){
if (err) throw err;
db=client.db("myDBS");
db.collection('users').updateOne({$set: data});
});

how to submit a form on the same post in the same page

So i am trying to submit a form on the same post (kinda like the comments on facebook or youtube where on a post you have a field you populate the field and submit then you are redirected to the same page but the post has a comment or in my case a tag added).
Schema
Tag schema
var mongoose = require("mongoose");
var tagSchema = new mongoose.Schema({
tagDescription: String
});
module.exports = mongoose.model("Tag", tagSchema);
Note Schema
var mongoose = require("mongoose");
var noteSchema = new mongoose.Schema({
title: String,
body: String,
category: String,
created: { type: Date, default: Date.now },
tags: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Tag"
}
]
});
module.exports = mongoose.model("note", noteSchema);
So I tried the following code but whenever i submit a tag the tags are added only to the first post, and if I remove findOne and replace it with find a cannot read property of push of undefined occurs.
this is the index.ejs page
<div class="card-body">
<h2 class="card-title"><%= note.title %></h2>
<div class="card-text-center">
<p><%= note.category %></p>
<p><%= note.body.substring(0,20)%>...</p>
<% note.tags.forEach(function(tag){ %>
<p><%= tag.tagDescription %></p>
<% }) %>
<div class="float-right card-footer">
<small><%= note.created.toDateString() %></small>
</div>
<p>Read More</p>
<form action="/" method="post">
<input class="col-md-2 form-control" type="text" name="tag[tagDescription]" placeholder="Tag" />
<button class="btn btn-primary">Submit</button>
</form>
Routes
app.post("/", function (req, res) {
Note.findOne({}, function (err, note) {
if (err) {
console.log(err);
res.redirect("/notes");
} else {
Tag.create(req.body.tag, function (err, tag) {
if (err) {
console.log(err);
} else {
note.tags.push(tag);
note.save();
res.redirect("/notes");
}
});
}
});
});
app.get("/notes", function (req, res) {
Note.find({}).populate("tags").exec(function (err, notes) {
if (err) {
console.log(err);
} else {
res.render("index", { notes: notes/*, tags: i */});
//console.log(i);
}
});
});
app.get("/notes/new", function (req, res) {
res.render("new");
})
app.post("/notes", function (req, res) {
Note.create(req.body.note, function (err, newNote) {
if (err) {
console.log(err);
} else {
res.redirect("/notes");
}
});
});
form submit for new note/post
<form action="/notes" method="post">
<div class="form-group">
<label>Title</label>
<input class="form-control" type="text" name="note[title]" placeholder="Title" />
</div>
<div class="form-group">
<label>Category</label>
<input class="form-control" type="text" name="note[category]" placeholder="Category" />
</div>
<div class="form-group">
<label>Note content</label>
<textarea class="form-control" name="note[body]" placeholder="Add a new Note..."></textarea>
</div>
<div class="form=group">
<button class="btn btn-primary btn-large btn-block">Submit</button>
</div>
</form>
When posting a tag, the route needs to know which note the tag belongs to. Instead of using findOne(), I would prefer the original solution that you were using by routing to notes/:id/tag and call
Note.findById(req.params.id, ...);
If you insist on posting to '/' as your route, you could pass the noteId as a parameter
<form action="/?noteId=<%= note.id %>" method="post">
and then catch it on your route
Note.findById(req.body.noteId, ...);
The trade offs for using nested resources in REST are discussed well here.
index
<% note.tags.forEach(function(tag){ %>
<div class="badge">
<div class="badge badge-pill badge-info">
<form action="/notes/<%= note._id %>/tags?_method=DELETE" method="post" style="display: inline">
<button class="btn btn-sm">x</button>
</form>
<%= tag.tagDescription %>
</div>
</div>
<% }) %>
<p>Read More</p>
<div class="float-right card-footer">
<small><%= note.created.toDateString() %></small>
</div>
<form action="/notes/<%= note.id %>/tags" method="post">
<input class="col-md-2 form-control" type="text" name="tag[tagDescription]" placeholder="Tag" />
<button class="btn btn-primary">Add Tag</button>
</form>
routes
app.post("/notes/:id/tags", function (req, res) {
Note.findById(req.params.id, function (err, note) {
if (err) {
res.redirect("/notes");
}
else {
Tag.create(req.body.tag, function (err, tag) {
if (err) {
console.log(err);
}
else {
note.tags.push(tag);
note.save();
res.redirect("/notes");
}
});
}
});
});
Note.find({}).populate("tags").exec(function (err, notes) {
if (err) {
console.log(err);
} else {
res.render("index", { notes: notes });
}
});

Resources