Reading mongodb to HBS (handlebars) template - node.js

I am trying to display data from my mongodb backend to an hbs template by trying to port over this tutorial. I do not get any errors from the server logs or the console in the browser, but I do not get any data represented on the template. Interestingly enough, however, it is generating html markup. Please help me see the issue.
*Note using express framework (and still learning)
app.js:
app.post("/", function(req, res){
res.render("default", {title:"posts", entries:myRoute.getBlogEntries()});
});
myRoute.js:
exports.getBlogEntries = function(res) {
mongo.connect("mongodb://localhost:27017/myDB", function(err, db){
if(err) { return console.dir(err); }
var collection = db.collection("posts");
collection.find({},{},function(e,docs){
res.render("default", {
"entries" : docs
});
});
});
};
hbs template:
{{#each entries}}
<form method="POST">
<div class="well">
<div class="row">
<div class="col-md-1">
<div>
<button type="submit" value="{{_id}}" class="btn btn-lrg btn-primary" name="voteup" title="Vote post up"><span class="glyphicon glyphicon-thumbs-up"></span></button>
</div>
<div style="text-align:center;padding-right:5px;padding-top:7px;padding-bottom:7px;"><span class="badge">{{voteCount}}</span></div>
<div>
<button type="submit" value="{{_id}}" class="btn btn-lrg btn-danger" name="votedown" title="Vote post down"><span class="glyphicon glyphicon-thumbs-down"></span></button>
</div>
</div>
<div class="col-md-10">
<h4>{{title}}</h4>
<label style="font-weight:normal;font-style:italic">Posted: {{published}}</label>
<div>
{{body}}
</div>
</div>
</div>
</div>
</form>
{{/each}}
Thanks in advance!

I assume you are using the mongodb driver,which you did not specify.
collection.find returns a mongodb cursor , not an array of documents. You can use toArray to get the documents :
collection.find().toArray(function(e,docs){
...
}
I suggest your read the documentation of the library before using it,because you just can guess what an api does.

Related

Cannot POST /admin Error return in web browser

I want to update my images on the blog page. but I got an error in the web browser like
Cannot POST /admin/portfolio/609911b1fba77be609396747/edit_cover
here is edit_cover.ejs file code and I use post method to submit images in the database
<%-include('./partials/header')%>
<div class="container-fluid">
<h1 class="text text-primary">Change Porfolio Cover Image Section</h1>
<div class="card shadow mb-4">
<div class="card-header">
<form action="/admin/portfolio/<%=work._id%>/edit_cover" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="exampleFormControlFile1">Cover</label>
<input type="file" name="cover" class="form-control-file" id="exampleFormControlFile1">
</div>
<div class="form-group">
<label for="exampleFormControlFile2">Snaps of Project</label>
<input class="form-control-file" name="images" type="file" id="exampleFormControlFile2" multiple>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success" >Update</button>
</div>
</form>
</div>
<div class="card-body">
<div class="table-responsive">
</div>
</div>
</div>
My router.js file code is here and two lines of code in here one is get request and other is for post
router.get('/admin/portfolio/:id/cover_edit',serverController.isAuthenticated,serverController.portfolio_edit_cover)
router.post('/admin/portfolio/:id/cover_edit',serverController.isAuthenticated,upload.fields([{name: "cover", maxCount: 1},{name: "images", maxCount: 12}]),serverController.portfolio_edit_cover_post)
here is my backend controller and code for images updating
exports.portfolio_edit_cover = async function(req,res){
res.render('server/edit_cover',{
work : await workCollection.findOne({_id: objectId(req.params.id)})
})
}
exports.portfolio_edit_cover_post = function(req,res){
let uploadImages = new Work(req.body, req.files, req.params.id)
console.log(req.files)
uploadImages.up().then((result)=>{
res.redirect('/admin/portfolio',{
work : result
})
}).catch(()=>{
res.send('404')
})
}
and lastly this all about my model codes. in the following code is just for how update my data onto databae
Work.prototype.up = function(){
return new Promise(async(resolve,reject)=>{
await workCollection.updateOne({_id : objectId(this.id)}, {$set :
{
images : this.images
}
}
)
resolve()
})
}
module.exports = Work
in edit_cover.js file it has path like
action="/admin/portfolio/<%=work._id%>**/edit_cover**" and router.js it's like
router.get('/admin/portfolio/:id**/cover_edit**',serverController.isAuthenticated,serverController.portfolio_edit_cover)
router.post('/admin/portfolio/:id**/cover_edit**',serverController.isAuthenticated,upload.fields([{name: "cover", maxCount: 1},{name: "images", maxCount: 12}]),serverController.portfolio_edit_cover_post)
both of these need to have the same path; everything is fine but at last segment, it should be /cover_edit

Render HTML Page with Json data

I have this issue:
I have a get request that I serve using router.get (Express).
In this function I use to take datas from my sql db. Now i have this data in JSON format. I want to pass the json datas to handlebars and to send the response to the client with the datas rendered inside the html only (Render is completely made on server side).
Maybe I' m getting a little bit confusing:
Is there a solution for what I want to do?
Express:
//CHAT
router.get('/chatlist', ensureAuthenticated, (req,res)=>{
let mittente = req.user.id;
findUsersChat(mittente)
.then(Chats=>{
getChatData(Chats,mittente).then(ChatList=>{
console.log("Lista2: " +ChatList);
var obj=JSON.parse(ChatList);
res.render('chatlist') ;
})
.catch(err=>console.log(err))
});
})
Handlebars
<section id="gigs" class="container">
<h1>Chats Available</h1>
{{#each obj}}
<h1>{{Nome}}</h1>
<div class="form-group">
<form method="POST" action="/users/chat">
<p>Utente numero : {{#index}}</p>
<label for="name" value={{Nome}}>{{Nome}}</label>
</form>
</div>
{{/each}}
</section>
It looks like you are not passing the array (ChatList) to your view.
You can do that by changing your code to this:
...
getChatData(Chats,mittente).then(ChatList=>{
console.log("Lista2: " +ChatList);
res.render('chatlist', {objects: ChatList}) ;
})
...
By doing this an array "objects" will be available in your view and you can iterator over it.
Your page now should become:
<section id="gigs" class="container">
<h1>Chats Available</h1>
{{#each objects}}
<h1>{{./Nome}}</h1>
<div class="form-group">
<form method="POST" action="/users/chat">
<p>Utente numero : {{#index}}</p>
<label for="name" value={{./Nome}}>{{./Nome}}</label>
</form>
</div>
{{/each}}
</section>

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

Uploading file to EC2 Web Server from Web Application

I am creating a simple application using Sails.js. What it basically does is it creates a new Item then saves it to the database and uploads the image to S3.
Here's what happens:
When I run my application on my local, it behaves okay. The req.body has contents, and the req.file('item-image') is not empty.
I am running it on EC2 now, and the problem is, the req.body is just an empty object, but the req.file('item-image') is not empty. I've tried different debugging scenarios, see them below:
If I remove the enctype="multipart/form-data" (I know this is needed for file upload, just trying), I get the req.body object that I expect, but as expected, the req.file('item-image') is empty.
I put back the enctype="multipart/form-data" then tried sending the request without the file, I get my expected req.body object.
I included an image on my request, the req.body object is empty, but the req.file('item-image') isn't.
The weirdest part is, when I send my request through postman, all behaves as expected. I'm really lost now, see my code below:
create_event.ejs
<form action=<%= event.createUrl %> method="POST" id="form-item" enctype="multipart/form-data">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="blue bigger">Please fill the following form fields</h4>
</div>
<div class="modal-body overflow-visible">
<div class="row">
<div class="col-xs-12 col-sm-5">
<div class="space"></div>
<input type="file" name="item-image"/>
</div>
<div class="col-xs-12 col-sm-7">
<div class="form-group">
<label for="form-field-username">Name</label>
<div>
<input class="input-large" type="text" id="form-field-username" placeholder="Item Name" name="item-name" />
</div>
</div>
<div class="space-4"></div>
<div class="form-group">
<label for="form-field-username">Description</label>
<div>
<input class="input-large" type="text" id="form-field-username" placeholder="Item Description" name="item-description"/>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-sm" data-dismiss="modal">
<i class="icon-remove"></i>
Cancel
</button>
<button class="btn btn-sm btn-primary" id="save-item">
<i class="icon-ok"></i>
Save
</button>
</div>
</div>
</div>
</form>
create_event.js
$('#save-item').on('click', function(e){
var response = confirm('Are you sure you want to continue saving this item?');
if(response == true) {
$('#form-item').submit();
}
});
AdminController.js
createItem: function(req, res){
console.log('Saving..');
console.log(req.body);
var eventId = req.path.split('/')[4];
req.file('item-image').upload(function callback(error, uploadedFile){
if(error) {
console.log(error);
return res.serverError();
}
console.log(uploadedFile);
s3Helper.upload(uploadedFile[0], function(error, data){
if(error) {
return res.serverError();
}
var item = {
ITEM_ID: uuid.v1(),
EVENT_ID: req.path.split('/')[4],
NAME: req.body['item-name'],
DESCRIPTION: req.body['item-description'],
IMAGE_URL: data.Location
}
EventItem.create(item, function(error, data){
if(error) {
console.log(error);
return res.serverError();
}
console.log('Successfully saved data: ');
console.log(data);
return res.redirect('/admin/events/' + eventId);
});
});
});
},
Thank you!
I found the answer here https://github.com/balderdashy/sails/issues/2508
Apparently, sails.js uses skipper and is sensitive on the order of the input. I just put the file part on the end and it now works.
I'm just confused as to why it works on my local, and not on my ec2 server.

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

Resources