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
}
Related
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");
}
})
});
So, I have this POST method in NodeJS that handles the login authentication
// Login logic
app.post("/home", function(req, res){
Item.findOne({EmailID: req.body.emailAddress}, function (err, docs) {
if(req.body.emailAddress === docs.EmailID && hash(req.body.password, docs.Salt) === docs.Password) {
currentUser = docs.FirstName;
console.log("Damn");
res.redirect("dashboard.html");
}
});
});
I can see in the console that "Damn" is printed, but for some reason, the redirect doesn't go to the following GET "dashboard.html" method as it is supposed to go but rather goes to the 404 error function
app.get("/dashboard.html", (req, res)=>{
console.log("here we go again");
Activity.find({}, function(err, foundItems){
res.render("home", {newListItems: foundItems});
});
});
and instead goes to the following 404 function. "here we go again" doesn't print on the console. Any idea on how to make the redirect go to the get function?
app.get("/*", function(req, res){
res.sendFile(__dirname + "/404.html")
});
This is my HTML
<form class="" action="/home" method="post">
<div class="">
<img class ="tent-image"src="assets/images/tent.png" alt width="90" height="72">
<h4 class="company">PASTIME</h4>
<h1 class="h3 mb-3 fw-normal"> Sign in</h1>
<h4 class="h3 fw-normal" style="color: <%= inputcolor %>"> <%= FirstLine %><br /> <%= SecondLine%> </h4>
<label for="inputEmail" class="virtually-hidden"></label>
<input id="inputEmail" name="emailID" class="form-control" placeholder="Email address" required="" autofocus="">
<label for="inputPassword" class="visually-hidden">Password</label>
<input type="password" name="passWORD" id="inputPassword" class="form-control" placeholder="Password" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button class="btn btn-dark" type="submit">Submit</button>
<p class="mt-5 mb-3 text-muted">© 2021 Pastime</p>
</form>
Please help
try by using
res.redirect("/dashboard.html");
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>
I am just stuck in a problem and also don't know whether the question is correct or not.
I am working on a node express js, using ejs templating engine.
I have created certain endpoints (say login(POST) endpoint) which are generic endpoints.
Now I want to create a new application which uses should use these endpoints and render the view according to the result of these endpoints.
Lets say I have a generic endpoint for login
router.post('/user/login', function (req, res) {
var userLoginId = req.body.username;
var currentPassword = req.body.password;
UserLogin.findOne({userLoginId: userLoginId, currentPassword: currentPassword}, function (err, usr) {
if (err) {
console.log('Error in User login');
console.log(err);
res.status(500).type('application/problem+json').send();
} else {
if (!usr) {
console.log('Please enter valid username and password');
res.status(404).type('application/problem+json').send();
} else {
res.type('application/json').status(200).send(usr);
}
}
});
});
And I am using this login.ejs file
<div class="container panel panel-primary">
<h2 class="h2 text-center">Login</h2>
<form class="form-horizontal" name="loginForm" method="post" action="/user/login">
<div class="form-group">
<label for="username" class="col-sm-offset-2 col-sm-2 control-label">UserName</label>
<div class="col-sm-4">
<input type="text" name="username" class="form-control" id="username" placeholder="username">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-offset-2 col-sm-2 control-label">Password</label>
<div class="col-sm-4">
<input type="password" name="password" class="form-control" id="password" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-4">
<button type="submit" class="btn btn-primary btn-">Sign in</button>
</div>
</div>
</form>
</div>
Now I want to use this code and want to login to the system.
If the user login is successful I want to redirect to dashboard page else same login page.
On executing this code the api returns me the JSON response and from this response how can I decide to whether to redirect on dashboard page or login page.
Please help if more input is needed please put a comment.
I would instead of doing a form request to login, do a AJAX request to login and then use something like jQuery to do the AJAX request and response. Alternatively you could do something like the following.
router.get('/login', function(req, res){
res.render('login', {});
})
router.post('/login', function (req, res) {
var userLoginId = req.body.username;
var currentPassword = req.body.password;
UserLogin.findOne({userLoginId: userLoginId, currentPassword: currentPassword}, function (err, usr) {
if (err) {
console.log('Error in User login');
console.log(err);
// res.status(500).type('application/problem+json').send();
res.status(500).render('login', { error : 'Error finding password'})
} else {
if (!usr) {
console.log('Please enter valid username and password');
// res.status(404).type('application/problem+json').send();
res.status(404).render('login', { error : 'Please enter valid username and password'})
} else {
res.redirect('/dashboard');
}
}
});
});
For the login.ejs file i would conditionally render the error.
<!DOCTYPE html>
<html>
<body>
<div class="container panel panel-primary">
<h2 class="h2 text-center">Login</h2>
<%if (locals.error) { %>
<%= error %>
<% } %>
<form class="form-horizontal" name="loginForm" method="post" action="/user/login">
<div class="form-group">
<label for="username" class="col-sm-offset-2 col-sm-2 control-label">UserName</label>
<div class="col-sm-4">
<input type="text" name="username" class="form-control" id="username" placeholder="username">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-offset-2 col-sm-2 control-label">Password</label>
<div class="col-sm-4">
<input type="password" name="password" class="form-control" id="password" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-4">
<button type="submit" class="btn btn-primary btn-">Sign in</button>
</div>
</div>
</form>
</div>
</body>
</html>
I want to get data of owner ID which lies between two dates using datePicker.
HTML
<form method="post">
<div class="col-lg-5 col-md-5">
<label>From</label>
<input type="date" class="form-control" ng-model="date.from" name="datefrom" />
</div>
<div class="col-lg-5 col-md-5">
<label>To</label>
<input type="date" class="form-control" ng-model="date.to" name="dateto" /> </div>
<div class="col-lg-2 col-md-2">
<button class="btn btn-primary " ng-click="getleaddate()">Go</button>
</div>
</form>
Node API
apiRoutes.post('/getleaddate', function(req, res){
var token=getToken(req.headers);
var owner=jwt.decode(token, config.secret);
Lead.find({ownerId:owner._id},date:{$gte :new Date(req.body.datefrom), $lte:new Date(req.body.dateto)},function(err, data){
if(err){res.json(err)}
else{
res.json(data);
console.log(data)
}
});
});
Above API is not working because req.body.datefrom and req.body.dateto is undefined
I don't know how to fix it.
please check the function for ng-click="getleaddate()"
Check the network tab on the request and request body sent .
it is working fine for me :
FormData:
datefrom:2017-01-11
dateto:2017-01-04
router.post('/test', function(req, res) {
console.log(req.body);
console.log(req.body.datefrom);
});
Console Output:
{ datefrom: '2017-01-11', dateto: '2017-01-04' }