Form: Keep posted parameters with Sails JS - node.js

I have file views/user/index.ejs
<form action="" method="POST>
<label>Username: </label>
<input type="text" class="form-control" value="<%= req.param('username') %>" name="username">
<input type="Submit" value="Submit">
</form>
Content of api/controllers/UserController.js
module.exports = {
index: function (req, res) {
sails.log(req.param('username'));
// Result: invest
}
}
Although the log print "invest", but the content of input is "undefined". I think that the array of requested parameters had not been kept.
Can anyone help me solve it? I will donate 2 eggs ;)

You can use this to pass variables to your view:
module.exports = {
index: function (req, res) {
return res.view("user/index", {username: req.param('username')});
}
}
In your view:
<input type="text" class="form-control" value="<%= username %>" name="username">

Related

blog post edit from MongoDB does not save changes in NodeJS, ejs template

I have created a blog site in NodeJS, EJS using mongodb. My problem is my posts show up from my database but I I want to make a change to it, it won't save.
app.js
app.post('/do-edit-post/:postId',(req, res) => {
const requestedPostId = req.params.postId;
Post.updateOne({ _id:requestedPostId }, {$set: {
title: req.body.title,
author:req.body.author,
content:req.body.content
}
}, function (err, result) {
if (err) {
console.log(err);
} else {
console.log("Post Updated successfully");
res.redirect("/admin");
}
});
});
In my editpostID.ejs:
<form class="" action="/do-edit-post" method="post">
<div class="form-group">
<label>Title</label>
<input class="form-control" hidden="<%= post._id %>">
<input class="form-control" text="text" name="postTitle" value="<%= title %>">
<label>Author</label>
<input class="form-control" text="text" name="postAuthor" value="<%= author %>">
<label>Post</label>
<!-- Text area matching the selector specified in the TinyMCE configuration -->
<textarea id="mytextarea" class="form-control" name="postBody" rows="5" cols="30" value=<%- content %>> </textarea>
</div>
<button class="btn btn-warning" type="submit" name="button">Save</button>
</form>
I even tried adding a hidden input field of ._id but it's not saving. What am I missing?
First of all you should add a input name on your hidden input
<form class="" action="/do-edit-post" method="post">
<div class="form-group">
<label>Title</label>
<input class="form-control" type="hidden" value="<%= _id %>" name="postId"> //<-- name added here also you should send the id on input value
<input class="form-control" text="text" name="postTitle" value="<%= title %>">
<label>Author</label>
<input class="form-control" text="text" name="postAuthor" value="<%= author %>">
<label>Post</label>
<!-- Text area matching the selector specified in the TinyMCE configuration -->
<textarea id="mytextarea" class="form-control" name="postBody" rows="5" cols="30" value=<%- content %>> </textarea>
</div>
<button class="btn btn-warning" type="submit" name="button">Save</button>
</form>
Then on node side you can get the id like this
app.post('/do-edit-post/:id',async (req, res) => {
const requestedPostId = req.body.postId; // <-- get the id from the form
await Post.findByIdAndUpdate(requestedPostId , {
title: req.body.title,
author:req.body.author,
content:req.body.content
}).catch(err => {
if (err){
console.log(err)
}else{
console.log("Post Updated successfully");
res.redirect("/admin");
}
})
});

Getting an error while saving hidden type data in mongodb database using nodejs

I have got two things in form the first is add a password and the other is id which is no need to enter as it comes from the database directly when I click on add I got an error
Post method is
router.post('/', checkLogin, function (req, res, next) {
var user = localStorage.getItem('loginname');
var add_model = new pass_cat({
password: req.body.catename,
user_id: req.body.id
})
add_model.save(function (err, doc) {
if (err) throw err;
res.render('AddCategory', {
title: 'Password Management System',
user: user,
msg: 'Inserted Successfully'
})
})
});
And the ejs code for the form is
<form action="/add_category" id="EmployeeForm" class="form-horizontal" method="post" role="form">
<input type="hidden" name="id" value="<%= data%>" >
<div class="form-group">
<label for="Username" class="col-md-3 control-label">Add Category Name</label>
<div class="col-md-9">
<input type="text" class="form-control" name="catename" placeholder="Enter Password Category">
</div>
</div>
<div class="form-group">
<label for="User_id" class="col-md-3 control-label">User_id</label>
<div class="col-md-9">
<input type="text" class="form-control" name="userid" value="<%=data[0]._id%>" placeholder="Enter Password Category">
</div>
</div>
<input type="hidden" name="id" value="<%= data%>" >
there is no need of this line in the form, as data you are not setting anywhere, and its value is not defined.

Why CSRF is not working in only POST route While working in the rest of other Post routes?

I am getting the CSRF forbidden error. However CSRF is working fine in the rest of the application like post route of logout, signUp, Signin deleteing anything et c..
But when I perform the post action in only one route `/addProduct" I am getting the error Note that I am generating my CSRF token before routes declaration.
I am attaching the main file code and the front end code of addProduct.
Here is my main file code where I am generating token and including it in all routes
app.use(csrfProtection);
app.use(flash());
// USed to include token and isLoggedIn information to render in every page
app.use((req, res, next) => {
res.locals.isLoggedIn = req.session.isLoggedIn;
res.locals.csrfToken = req.csrfToken();
res.locals.user= req.session.user;
next();
});
// app.use((req, res, next) => {
// // throw new Error('Sync Dummy');
// if (!req.session.user) {
// return next();
// }});
app.use(multer({ storage: fileStorage,fileFilter:fileFilter }).single('image'));
app.use(shopRoute);
app.use(authRoute);
app.use('/admin',adminRoute);
app.use(errorController.get404);
This is the front end code for ADD_Product.ejs. Here I am including hidden input as well... to get CSRF value back to check it...
<form action="<%=path%>" enctype="multipart/form-data" method="POST">
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title" value="<%=product.title%>" >
</div>
<div class="form-group">
<label for="price">Price</label>
<input type="text" class="form-control" id="price" name="price" value="<%=product.price%>">
</div>
<div class="form-group">
<input type="file" class="form-control-file" id="exampleFormControlFile1" name="image" value="<%=product.imageUrl%>">
</div>
<div class="form-group">
<label for="exampleFormControlTextarea1">Description</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3" name="description" value="<%=product.description%>"></textarea>
</div>
<% if (path=="/admin/edit") { %>
<input type="hidden" name="productId" value="<%=product._id%>">
<% } %>
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<button type="submit" class="btn btn-primary btn-lg center">+ </button>
</form>

why am i getting forbidden error in only one post Route?

i am getting the CSRF forbidden error .
However csrf is working fine in the rest of the application like post route of logout,signUp,Signin deleteing anything e.t.c/.
But when i perform the post action in only one route "/addProduct"
i got the error
Note that i am generating my CSRF token before routes declaration.
I am attaching the main file code and the front end code of addProduct.
here is my main file code where i am generating token and including it in all routes
app.use(csrfProtection);
app.use(flash());
// USed to include token and isLoggedIn information to render in every page
app.use((req, res, next) => {
res.locals.isLoggedIn = req.session.isLoggedIn;
res.locals.csrfToken = req.csrfToken();
res.locals.user= req.session.user;
next();
});
// app.use((req, res, next) => {
// // throw new Error('Sync Dummy');
// if (!req.session.user) {
// return next();
// }});
app.use(multer({ storage: fileStorage,fileFilter:fileFilter }).single('image'));
app.use(shopRoute);
app.use(authRoute);
app.use('/admin',adminRoute);
app.use(errorController.get404);
This is the front end code for ADD_Product.ejs
here i am including hidden input as well...
to get csrf value back to check it...
<form action="<%=path%>" enctype="multipart/form-data" method="POST">
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title" value="<%=product.title%>" >
</div>
<div class="form-group">
<label for="price">Price</label>
<input type="text" class="form-control" id="price" name="price" value="<%=product.price%>">
</div>
<div class="form-group">
<input type="file" class="form-control-file" id="exampleFormControlFile1" name="image" value="<%=product.imageUrl%>">
</div>
<div class="form-group">
<label for="exampleFormControlTextarea1">Description</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3" name="description" value="<%=product.description%>"></textarea>
</div>
<% if (path=="/admin/edit") { %>
<input type="hidden" name="productId" value="<%=product._id%>">
<% } %>
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<button type="submit" class="btn btn-primary btn-lg center">+ </button>

Calling a PUT to express from EJS

I am trying to call a restful api created in expressjs from EJS form.
I tried looking on google and stackoverflow, and trying lots of different methods.
orders.ejs:
<ul class="orders">
<% for(var i=0; i<orders.length; i++) {%>
<ul class="order">
<p> coffee_id <span><%= orders[i].name %></span>
amount: <span><%= orders[i].amount %></span>
quantity <span><%= orders[i].quantity %></span> </p>
</ul>
<% } %>
</ul>
<div>
<form action="/orders" method="POST" action="orders/?_method=PUT">
<input type="text" placeholder="username" name="username">
<input type="text" placeholder="coffee name" name="name">
<input type="number" placeholder="amount" name="amount">
<input type="number" placeholder="quantity" name="quantity">
<button type="submit" id="order" >Submit</button>
</form>
</div>
nodejs.app.js:
app.post('/orders', (req, res) => { // falta o EJS
db.collection('orders').save(req.body, (err, result) => {
if (err) return console.log(err)
console.log(req.body);
res.render('orders.ejs', {
put: true
});
})
})
app.put('/orders/:coffeeid/:quantity', function(req, res) { ...
}
This code works fine individually calling them from Postman with the right parameters, but I need to call them both when I submit the EJS form.
app.get('/orders/:coffeeid',function(req, res) {
db.collection('orders').find({_id:req.params.coffeeid}).toArray, function(error,result){
if(!error && result && quantity){
return res.render('orders.ejs',{orders: result, coffeeid:result.coffeeid, quantity:'7'}); // <-- pass coffeeid to view
}
}
});
I need to read quantity also from the form and check for stock in the PUT, so for now I fixed it at '7'units, but now Cannot GET /orders
route for get orders :
app.get('/orders',function(req, res) {
// fetch all orders and display it to view
});
route for display edit page of order by coffeeid :
app.get('/orders/:coffeeid',function(req, res) {
var coffeeid= req.params.coffeeid;
db.collection('orders').find({_id:coffeeid}).toArray,function(error,result){
if(!error && result){
return res.render('orders.ejs',{orders:result,coffeeid:result.coffeeid, quantity:'7'});
}
});
});
form :
<form action="/orders/<%=coffeeid%>" method="POST">
<input name="_method" type="hidden" value="PUT">
<input type="text" placeholder="username" name="username">
<input type="text" placeholder="coffee name" name="name">
<input type="number" placeholder="amount" name="amount" value="">
<input type="number" placeholder="quantity" name="quantity" value="<%=quantity%>">
<button type="submit" id="order" >Submit</button>
</form>
to update information route will be :
app.put('/orders/:coffeeid', function(req, res) {
var coffeeid= req.params.coffeeid;
var quantity= req.body.quantity;
// save to database
}

Resources