Can't update user model in express? - node.js

I'm trying to do a put request to update a user model but instead my router just sends another get request.
Here's my router
router.get('/update', isLoggedIn, function(req, res) {
res.render('update.ejs', {
user : req.user // get the user out of session and pass to template
});
});
router.put('/update', function(req, res) {
var username = req.body.username;
var profile_type = req.body.prof_type;
var pic = req.body.profile_pic;
var aboutme = req.body.whoami;
console.log(req.body.whoami);
User.findById(req.params.id,function(err, userup){
if (!userup)
return next(new Error("Couldn't load user"));
else {
userup.username = username;
userup.prof_type = profile_type;
userup.profile_pic = pic;
userup.whoami = aboutme;
userup.save(function(err) {
if (err)
console.log('error on update');
else
console.log('successful update');
});
}
});
res.redirect('/profile');
});
Here's my html input form
<form action="/update" method="put">
<div class="form-group">
<label>Username</label>
<input type="text" class="form-control" name="username">
</div>
<div class="form-group">
<h2> Pick a type of profile</h2>
<input type="radio" class="form-control" name="prof_type" value="true">Tutor<br>
<input type="radio" class="form-control" name="prof_type" value="false">Student
</div>
<div class="form-group">
<label>Link to profile picture</label>
<input type="text" class="form-control" name="profilepic">
</div>
<div class="form-group">
<label>About me</label>
<textarea name="whoami" class="form-control">Enter text here </textarea>
</div>
<button type="submit" class="btn btn-warning btn-lg">Update</button>
</form>
I've also tried changing them to be /update/:username, however, after I click the update button with the fields, I GET this address
http://localhost:3000/update?username=bob&prof_type=false&profilepic=bob&whoami=bob
Not sure why I'm not updating the model or even why it's not putting. Any help is much appreciated, thanks!

HTML only supports GET and POST requests. See the specification for details:
The method and formmethod content attributes are enumerated attributes
with the following keywords and states:
The keyword get, mapping to the state GET, indicating the HTTP GET
method. The keyword post, mapping to the state POST, indicating the
HTTP POST method. The invalid value default for these attributes is
the GET state. The missing value default for the method attribute is
also the GET state. (There is no missing value default for the
formmethod attribute.)
You can use the PUT method only with an ajax request. For example in jQuery:
$.ajax({
url: '/update',
type: 'PUT',
success: function(result) {
// Do something with the result
}
});

Related

Update Operation in MongoDB with NodeJs

I am working on a Blog WebSite with CRUD operation I am able to achieve CRD operations but have issues with update One.
Issue:-
When I click on the edit button it opens the compose tab with the textfile loaded successfully but when I click on update it redirects to the home page but nothing Update, Please help me get out from this.
//This is the code for edit & Update Route
app.get("/posts/:postId/edit", (req, res) => {
Post.findById(req.params.postId, (err, post) => {
if (err) {
console.log(err);
} else {
res.render("edit", { post: post });
}
});
});
app.post("/posts/:postId/edit", (req, res) => {
Post.findByIdAndUpdate(
req.params.postId,
{
$set: {
title: req.body.title,
content: req.body.content,
},
},
(err, update) => {
if (err) {
console.log(err);
} else {
console.log("Post Updated");
res.redirect("/");
}
}
);
});
Form for the Edit/Update
//This is the Edit ejs file containing the update form
<form action="/posts/<%=post._id%>/edit/?_method=PUT" method="post">
<div class="mb-3">
<label for="post-title">Title</label>
<input class="form-control" id="post-title" name="postTitle" type="text" placeholder="Input title"
required autocomplete="off" value="<%=post.title%>">
</div>
<div class="mb-3">
<label for="postcontent">Post</label>
<textarea class="form-control text-area" id="postcontent" name="blog" rows="4" cols="50" required
placeholder="Start writing your blog ..............."><%=post.content%></textarea>
</div>
<button class="btn btn-primary publish-btn" type="submit" name="button">Update</button>
</form>
Your error is from the Ejs
You didn’t rename your req.body well to match your incoming data
You were meant to be used title instead of postTitle
And content instead of blog
Just edit your ejs to this and test gee
<form action="/posts/<%=post._id%>/edit/?_method=PUT" method="post">
<div class="mb-3">
<label for="post-title">Title</label>
<input class="form-control" id="post-title" name=“title" type="text" placeholder="Input title"
required autocomplete="off" value="<%=post.title%>">
</div>
<div class="mb-3">
<label for="postcontent">Post</label>
<textarea class="form-control text-area" id="postcontent" name="content" rows="4" cols="50" required
placeholder="Start writing your blog ..............."><%=post.content%></textarea>
</div>
<button class="btn btn-primary publish-btn" type="submit" name="button">Update</button>
</form>
If this answers your question mark it as done

Post request with a JWT

I have a route which posts in /verify/:token, where :token is a jwt, but in my view the form sends a post request to /verify/:token and then in my route logic I get a invalid jwt because :token is being send, how can I fix this?
<form action="/verify/:token" method="POST">
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input id="passcode" type="text" class="form-control" name="passcode" placeholder="Pass Code" required>
</div>
<button type="submit" class="btn btn-primary" style="display: inline-block;">Verify</button>
</form>
Pass token to your form page router
router.get("/", function (req, res, next) {
jwt.sign({_id: user._id}, jwtSecret, { expiresIn: '5m' }).then((token) => {
res.render("postForm", {
token: token
});
});
});
now you can use token in hidden input field assuming you are using ejs in client
<form action="/verify" method="POST">
<div class="input-group form-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input id="token" type="hidden" class="form-control" name="token" value="<%= token %> ">
<input id="passcode" type="text" class="form-control" name="passcode" placeholder="Pass Code" required>
</div>
<button type="submit" class="btn btn-primary" style="display: inline-block;">Verify</button>
</form>
Assuming you have jQuery in the client side, you have to prevent the default action of form when it is submitted. Then you have to send the ajax request by taking the value of the input field
$('form').submit(function(e){
//prevent default
e.preventDefault();
let token = $('#passcode').val();
let url = "/verify/" + token;
$.post( url, function( data ) {
// Do something once the ajax call succeeds
}).fail(function() {
alert( "error" );
});
});

Submitting a form results to a url segment undefined in NodeJs

I am setting up a simple form submission, when I submit the form the url becomes undefined
This is the view: http://localhost:3000/dashboard/tours/categories
router.get('/tours/categories', function (req, res) {
res.render('agents/tourcategories', {
page_link: 'wishlist'
});
});
This is the form:
<form method="POST" action="/dashboard/tours/categories" >
<div class="box_general padding_bottom">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Category Name</label>
<input type="text" name="categoryname" class="form-control" placeholder="e.g Hiking">
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary pull-left" type="button" data-
dismiss="modal">Cancel</button>
<button id="" type="submit" class="btn btn-primary" >Save</a>
</div>
</form>
when I submit the form tne url changes to: `
http://localhost:3000/dashboard/tours/undefined
router.post('/tours/categories',function (req, res) {
console.log("We are here");
const category = new CategoriesDB({
categoryname: req.body.categoryname,
addedby: res.locals.useremail
});
// Save a Customer in the MongoDB
CategoriesDB.save(function (err) {
if(err){
console.log(err);
return;
}else{
res.redirect('/tours/categories');
}
})
});
I realy dont know where the undefined came from, I have checked everything seems to be okay. It keeps popping up in the url everythime i submit the form
`
From the snippets of the code you have posted, It might be because u have not used the middleware
router.all("/dashboard*");
But if u have used that and the GET request is working but not the POST then u will need to post more snippets of your code, mainly the middleware you defined to handle the routes

How to write Mongo query to find data between dates

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' }

Shortcut to adding req values to a response for rendering in Express View

I'm using Node/Express (most recent production versions)
I have a form where I collect new account info. The user can add a username, etc.
In the view handler, I check a mongodb database to see if the username is unique. If it is not, I generate a message and reload the original view. Since the original request was a post, all of the data the user posted is in req.body. I would like to add the data the user submitted on the response. I could do it by specifically adding each value to the response. But isn't there an easier way to add all the request data back to the response? And is there a way to render that in the view (i'm using ejs) I tried res.send(JSON) coupled with ejs variables. Doing so generates errors saying the variables aren't available.
Here's my function (ignore the users.createUser(req) - it's not finished yet):
createAccount: function(req, res, next){
users.createUser(req);
res.render('create_account', {
layout: 'secure_layout',
title: 'Create Account',
givenName: req.body.givenName,
username: req.body.username,
familyName: req.body.familyName
});
},
And here's my view:
<form action="/createAccount" method="post">
<div>
<label>First Name:</label>
<input type="text" name="givenName" value="<%= givenName %>"/><br/>
</div>
<div>
<label>Last Name:</label>
<input type="text" name="familyName" value="<%= familyName %>"/><br/>
</div>
<div>
<label>Username:</label>
<input type="text" name="username" value="<%= username %>"/><br/>
</div>
<div>
<label>Password:</label>
<input type="password" name="password"/>
</div>
<div>
<input type="submit" value="Submit"/>
</div>
</form>
It seems overly complex to have to add each of the values. I tried {body: req.body} but values were never added to the view.
I'm not quite sure what you're after, but if you want to render an ejs view with data that was on the request body, you would do something along these lines:
app.post('/foo', function(req, res, next) {
res.render('view', {body: req.body});
});
view.ejs:
<ul>
<% for(var key in body) { %>
<li><%= key %>: <%= body[key] %></li>
<% } %>
</ul>

Resources