I'm trying to fetch the data , but when i console it.I' getting the data but in rendering it's not working in front end its showing product is not defined.
app.get('/profile/profile/dashboard/update/:id',function (req,res,next) {
//console.log("hello "+req.params.id);
Product.findOne({_id: req.params.id}).then(product=>{
console.log("hello check please "+ product);
});
res.render('update.ejs',{ product: product });
});
update.ejs file
<% if (product._id) { %>
<tbody>
<td><input type="text" value="<%= product.name %>" required></td>
<td><input type="text" value="" required></td>
<td><input type="text" value="" required></td>
<td><input type="text" value="" required></td>
<td><input type="submit" class="btn btn-danger" value="submit"></td>
</tbody>
<% } %>
The problem is that you are trying to render the data before the findOne is finished. findOne is asynchronic function and that is why the log works for you.
Move res.render inside the then scope:
Product.findOne({_id: req.params.id}).then(product=>{
console.log("hello check please "+ product);
res.render('update.ejs',{ product: product });
});
Yes problem with your code is rendering is placed outside of the find one method. Put it inside the braces like.
app.get('/profile/profile/dashboard/update/:id',function (req,res,next) {
//console.log("hello "+req.params.id);
Product.findOne({_id: req.params.id}).then(product=>{
console.log("hello india "+ product);
res.render('update.ejs',{ product: product });
});
});
Related
I'm trying to insert the title from my input form into my caption column in my database and then display it with the post. The image and delete buttons display, however the title does not.
Here is my route in my server.js:
app.post('/newPost', isLoggedIn, uploads.single('inputFile'), (req, res) => {
console.log('On POST route');
// get an input from user
let file = req.file.path;
console.log(file);
cloudinary.uploader.upload(file, (result) => {
console.log(result);
db.post.create({
caption: req.body.title,
image_url: result.url,
userId: req.body.id
})
// Render result page with image
}).then((post) => res.render('index', { image: result.url }));
})
Here is my newPost.ejs which contains the form:
<div class="postSection">
<form action="/" method="POST" enctype="multipart/form-data">
<input type="title" placeholder="Write a Caption:" id="postText">
<input type="file" name="inputFile" id="inputFile">
<input type="submit" class="btn btn-primary" id="postSubmit" value="Post">
</form>
</div>
And, finally here is my index.ejs page in which it will display:
<div>
<% posts.forEach(function(post) { %>
<h1><%= post.caption %></h1>
<img class="images" width="700px" height="500px" src="<%= post.image_url %>" alt="uploaded image">
<form action="/<%= post.id %>?_method=DELETE" method="POST">
<input id="deleteButton" class="btn-danger" type="submit" value="Remove idea" >
</form>
<br>
<% }) %>
</div>
Can anyone spot why the title isn't being inserted into my database and also why it isn't displaying?
One option to debug is console.log the req.body and search for the text you sent as the title.
I think that the title is in req.body.postText or you should add a name tag to your title input and that will be the name in your req.body.
Let me know if this helps!
I have a form which dynamically adds user data from the user into a table.
This is the final form look
When one of these Use this account is pressed it shows, Cannot POST /like.
This is the form. I useEJS.
<form method="POST" autocomplete="off">
<div class = "form-group col-sm-12">
<label for="tagsarray">Enter Tags</label>
<input type="text" class="form-control" id="likes" name="likes" aria-placeholder="Enter tags seperated by a comma">
</div>
<div class="form-group col-sm-7">
<label for="numberoftimes">Enter Number of Actions</label>
<input type="text" class="form-control" id="action" name="action" aria-placeholder="Enter No. of Actions">
</div>
<% if (accounts) {%>
<table class = "striped">
<tbody>
<% accounts.forEach(accounts => { %>
<tr>
<td><%= accounts.title%></td>
<td><button type="submit" class = "btn btn-primary col-auto" >Use this account</button></td>
</tr>
</tr>
<%});%>
</tbody>
</table>
<%} else {%>
<p>You have no accounts added</p>
<% } %>
</form>
This is my controller.js
control.get('/like', async(req, res) => {
try{
const accounts = await account.find({user: req.user.id}).lean()
res.render("backend/like", {
name: req.user.name,
accounts
});
} catch(err) {
console.log(err)
}
});
control.post('/like/:id', getuserdata, (req, res, next) => {
try{
let title = res.accountuser.title;
let pass = res.accountuser.password;
let tags = req.body.likes;
let actions = req.body.action;
console.log(title, pass, tags, actions)
iglike(title, pass, tags, actions)
next();
res.redirect('/like')
}catch(err) {
console.log(err)
}
});
This does not catch any error and the console shows absolutely nothing. The only error is Cannot POST /like.
This is the getuserdata function for reference
async function getuserdata(req, res, next) {
let accountuser
try{
accountuser = await account.findById(req.params.id)
} catch(err) {
console.log(err)
}
res.accountuser = accountuser
next()
};
I have tried with a simple type=submit button with no href still shows the same error
Please help me solve this Cannot POST /like error.
You have to set a default action for your form, to make the route to work with post. If you use href it does a get by default.
To make a post in your route, you should remove the href and put an default action in your form.
<form method="POST" autocomplete="off" action="/like/<%= accounts._id%>">
Then in the line your have the submit button, remove the href (as it was moved to default action from form)
<td><button type="submit" class = "btn btn-primary col-auto" >Use this account</button></a></td>
/like is a GET request
for POST request you need to use
/like/1
where 1 can be any parameter
I have tried restarting the server multiple times. I also removed the node modules and installed it again. I also cleared the cache and also restarted VS code many time. Nothing seems to be working. Now after writing foundList.items.push(item); i cannot add items to my route directory as well. Before this i was able to add or delete items from the route directory. Can anyone please help me with this?
Here is my code for Express:
app.post("/", function (req, res) {
const itemName = req.body.newItem;
const listName = req.body.list;
const item = new Item({
name: itemName,
});
//Check id the user tried to add the list is default list or the custom list. Then find the custom list and add the new item and redirect to the custom list i.e ///listName
if (listName === "Today") {
item.save();
res.redirect("/");
} else {
List.findOne({ name: listName }, function (err, foundList) {
foundList.items.push(item);
foundList.save();
res.redirect("/" + listName);
});
}
});
Here is my EJS code as well.
<div class="box heading">
<h1><%= listTitle %></h1>
</div>
<div class="box">
<% newListItems.forEach(function(item) { %>
<form action="/delete" method="POST">
<div class="item">
<input
type="checkbox"
name="checkbox"
value="<%= item._id %>"
onChange="this.form.submit()"
/>
<p><%=item.name%></p>
</div>
</form>
<%});%>
<form class="item" action="/" method="post">
<input
type="text"
placeholder="newItem"
name="newItem"
autocomplete="off"
/>
<button type="submit" name="button" value="<%= listTitle %>">+</button>
</form>
</div>
It looks like my Udemy training course I am doing. I am pretty new to coding and have spent couple of hours trying to fix the same code. Anyways:
try to change the line: foundList.items.push(item); to singular: foundList.item.push(item); I can't see your listSchema in the code. Check it and see if you have "item" or "items".
const listSchema = {
name: String,
item: [itemsSchema]
};
I had item declared in the schema but was calling items in "foundList.items.push(item), and the server was crushing all the times.
It is landing into error as listName case is not matching with the list items available. require and install lodash and try using:
const listName= _.lowerCase(req.body.list);
I need to update the comment status, i.e. the name of the "approve" field. To this end, I created the AJAX script also the backend seems correct because it receives a message after clicking the button. I don't know why I can't save the "approve" value to the database. Please help. I use NodeJS, MongoDB, Express, and EJS for frontend.
My database:
My frontend:
<% post.comments.forEach(function (comment) { %>
<tr>
<td> <%= comment._id %> </td>
<td> <%= comment.username %> </td>
<td> <%= comment.comment %> </td>
<form method="post" onsubmit="return doApprove(this);">
<input type="hidden" name="post_id" value="<%= post._id %>" />
<input type="hidden" id="comment_id" name="comment_id">
<td> <input class="approve-comment" type="checkbox" name="approve" value="true">
<button class="btn btn-info" value="Approve"/>
</td>
</form>
<% }) %>
</tr>
</table>
</div>
<script>
function doApprove(form) {
var formData= {approve:form.approve.value};
$.ajax({
url: "/do-edit-comment",
method: "POST",
data: formData,
success: function (response) {
formData._id =response._id;
alert(response.text);
}
});
return false;
}
</script>
My backend:
app.post("/do-edit-comment", function (req,res) {
blog.collection("posts").updateOne({
"_id": ObjectId(req.body.id),
"comments._id": ObjectId(req.body.id)
},{
$set: {
"comments": {approve: req.body.approve}
}
}, function (error,document) {
res.send({
text: "comment approved"
});
});
});
To update a single element from an array, what you need is the $[<identifer>] array update operator. For the scenario described in your question, the update query in the server should be something like this:
blog.collection("posts").updateOne(
{ "_id": ObjectId(req.body.post_id), },
{ $set: { "comments.$[comment].approve": req.body.approve } },
{ arrayFilters: [{ "comment._id": ObjectId(req.body.commentId) }] },
function (error, document) {
res.send({
text: "comment approved"
});
}
)
EDIT(Front-end issues/fix)
So I figured there are some issues with the front end code too. This edit attempts to explain/fix those issues.
Issues:
1. The backend expects a commentId in the request object(req.body.commentId) to be able to identify the comment to update but you are not sending that from the front end.
2. The backend needs the id of the post to uniquely identify the post to update, but you are not sending that from the front end.
3. The approve value in the form data sent from the front-end is a string and it would always be "true". This is not what you want, you want to send a boolean value(true or false) depending on if the checkbox is checked or not.
Fix:
Update the form template to this:
<form method="post" onsubmit="return doApprove(event);">
<input type="hidden" name="post_id" value="<%= post._id %>" />
<input type="hidden" id="<%= comment._id %>" name="comment_id" />
<td> <input class="approve-comment" type="checkbox" name="approve" value="true">
<button class="btn btn-info" value="Approve"/>
</td>
</form>
Changes:
- The doApprove handler attached to the submit event of the form is now called with event instead of this.
- I updated the value of the id attribute for the input#name="comment_id" element to the actual comment._id value.
And in the script tag, update the doApprove function to this:
function doApprove(event) {
event.preventDefault();
const form = event.target;
var formData = {
approve: form.approve.checked, // form.approve.checked would be true if the checkbox is checked and false if it isn't
post_id: form.post_id.value, // The value of the input#name=post_id element
commentId: form.comment_id.id, // The id attribute of the input#name=comment_id element
};
$.ajax({
url: "/do-edit-comment",
method: "POST",
data: formData,
success: function (response) {
formData._id =response._id;
alert(response.text);
}
});
return false;
}
I hope that helps.
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' }