im currently trying to create an event to and store it in my mongo database. Below is my current event schema.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//blueprint for each new entry in the db
var eventSchema = new Schema({
eventName: {type:String},
eventDate: {type:String},
eventPlace:{type:String},
eventPrice: {type: Number}
});
module.exports = mongoose.model('Event', eventSchema);
Here is my create function code in my user.js file
// /route for new event
router.get('/newEvent', function (req,res,next) {
var messages = req.flash('error');
res.render('user/newEvent',{csrfToken: req.csrfToken(),messages: messages, hasErrors: messages.length >0});
});
//route for new event save
router.get('/createEvent', function(req, res, next) {
var event = new Event();
eventName = req.body.eventName;
eventDate = req.body.eventDate;
eventPlace = req.body.eventPlace;
eventPrice = req.body.eventPrice;
event.save(function(err) {
if(err) return next(err);
res.json({ message : 'Success!'});
});
});
And here is my form to create the new event in my newEvent.hbs file.
<div class = "row">
<div class="col-md-4 col-md-offset-4">
<h1> Create a new Event</h1>
{{#if hasErrors}}
<div class=alert alert-danger">
{{# each messages}}
<p>{{this}}</p>
{{/each}}
</div>
{{/if}}
<form action="/user/newEvent" method="post">
<div class="form-group">
<label for="eventName">Event Name</label>
<input type="text" id="eventName" name="eventName"class="form-control">
</div>
<div class="form-group">
<label for="eventDate">Event Date</label>
<input type="text" id="eventDate" name="eventDate" class="form-control">
</div>
<div>
<label for="eventPlace">Place of Event</label>
<input type="text" id="eventPlace" name="eventPlace" class="form-control">
</div>
<div>
<label for="eventPrice">Price of Event: €</label>
<input type="text" id="eventPrice" name="eventPrice" class="form-control">
</div>
<input type="hidden" name="_csrf" value="{{ csrfToken}}">
Create Event
</form>
</div>
So far when i run the code I get an error stating that the eventName, eventPlace, eventDate and eventPrice are required and havent been entered but when i remove the "required:true" from the events schema a new event is created but no data is stored in the database.
1- You are not saving the events correctly eventName = req.body.eventName
currently you are saving empty object, thats why when you remove required it save empty data.
2- You are also using req.body with get request you should be using router.post
Check the code below
router.post('/createEvent', function(req, res, next) {
var event = new Event({
eventName:req.body.eventName,
eventDate : req.body.eventDate,
eventPlace : req.body.eventPlace,
eventPrice : req.body.eventPrice
});
event.save(function(err) {
if(err) return next(err);
res.json({ message : 'Success!'});
});
});
Related
So I've been trying to figure out for hours, how to pass an error from a POST route in Express to an EJS template. I'm building a blog app and I want to prevent the redirect to the root route and instead display an error if the title input or text area are empty. Can this be done server-side or do I have to track the inputs on the client-side?
Here is my Compose template:
<form action="/compose" method="POST">
<div class="form-group">
<label for="postTitle">Title</label>
<input type="text" name="postTitle" class="form-control" id="postTitle" autocomplete="off">
<label for="postBody">Post</label>
<textarea name="postBody" class="form-control" autocomplete="off" rows="8"></textarea>
</div>
<button type="submit" name="button" class="btn btn-primary">Publish</button>
</form>
Here's my GET and POST routes:
compose_get: (req, res) => res.render("compose"),
compose_post: (req, res) => {
const postTitle = req.body.postTitle;
const postBody = req.body.postBody;
let postDate = new Date();
const post = new Posts({
date: postDate,
title: postTitle,
content: postBody
});
post.save(err => {
if (!err) {
res.redirect("/");
}
});
}
I am using ObjectReferences and push the comment data to the database but it's not working Even the data is being saved but only 'id' get added, not the user and comment
Main File with Push Method
var Comment = require('./models/comments'),
Camp = require('./models/user');
app.post('/camp/:id/comment', (req,res)=>{
Camp.findById(req.params.id, (err, idf)=>{
if(err){
console.log(err);
}else{
Comment.create(req.body.comment, (err, commentz)=>{
if(err){
console.log(err);
}else{
console.log(commentz + idf);
idf.comments.push(commentz)
idf.save();
res.redirect('/camp/'+ idf._id)
}
})
}
})
})
ObjectReferences user.js
var mongoose = require('mongoose');
var schema = mongoose.Schema;
var blogSchema = new schema({
name : String,
email : String,
descr : String, // TEMPORERY
posts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Post'
}
],
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Comment'
}
]
});
var Camp = mongoose.model("Camp", blogSchema);
module.exports= Camp;
CommentSchema comments.js
var mongoose = require('mongoose');
var schema = mongoose.Schema;
var cSchema = new schema({
user : String,
comment : String,
})
var Comment = mongoose.model("Comment", cSchema);
module.exports =Comment;
Main Form
<form action="/camp/<%=camp._id%>/comment" method="post" class="form-group">
<div class="form-group">
<input class="form-control" type="text" name="comment[user]" value="" placeholder="Name">
</div>
<div class="form-group">
<textarea class="form-control" style="height:100px" type="text" name="comment[comment]" value="" placeholder="Your Comment"></textarea>
</div>
<div class="form-group">
<button class="btn btn-primary btn-large btn-block" type="submit" name="submit"> SUBMIT</button>
</div>
</form>
The only ID added to the user's database, not all comments and in the comment, collection data added perfectly
I think instead of using commentz use commentz._id and have a callback for .save. It should work.
console.log(commentz + idf);
idf.comments.push(commentz._id)
idf.save(function(err){
if(err){
// handle error
}
res.redirect('/camp/'+ idf._id)
});
I'm creating a blog and in the blog you can add comments (obviously). In my mongodb schema the comment object is as follows:
var commentSchema = mongoose.Schema({
id: mongoose.Schema.Types.ObjectId,
text: String,
created: {type: Date, default: Date.now},
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String,
image: String
}
});
I'm extracting the timestamp (created) and displaying it when a comment is posted using the following:
<div id="comments">
<% blog.comments.forEach(function(comment){ %>
<div class="jumbotron comment">
<div class="row">
<div class="col-md-1">
<img class="comment-ico" src = "<%=comment.author.image%>">
</div>
<div class="col-md-7">
<h4><%=comment.author.username%></h4>
</div>
<div class="col-md-4 date">
<%= comment.created.toDateString()%>
</div>
</div>
</div>
<div><p><%=comment.text%></p></div>
However, this is just displaying the date in the following format: Fri Mar 24 2017
What I would like to display is a time since comment was posted. For example: "1 min ago", "10 mins ago" etc. How can I use JS to display this?
And on a similar note, if I want to display the date, how can I reformat to mm/dd/yyyy?
Thanks
Update:
Here is my comments create route which is stored in routes/comment.js:
router.post("/", middleware.isLoggedIn, function(req, res){
// lookup blog using id
Blog.findById(req.params.id, function(err, blog){
if(err) {
console.log(err);
res.redirect("/blogs");
} else {
// create new comment
Comment.create(req.body.comment, function(err, comment){
if(err) {
req.flash("error", "Something went wrong");
console.log(err);
} else {
comment.author.id = req.user._id;
comment.author.username = req.user.username;
comment.author.image = req.user.image;
comment.save();
// connect new comment to campground
blog.comments.push(comment);
blog.save();
var commentCreated = comment.created.toDateString();
if(req.xhr){
res.json({comment: comment, commentCreated: commentCreated, blog: blog});
} else {
// // redirect to campground show page
req.flash("success", "Successfully added comment");
res.redirect("/blogs/" + blog._id);
}
}
});
}
});
});
And then I am using AJAX in a separate file (/public/ajax.js) to display asynchronously:
$('#newComment').submit(function(e){
e.preventDefault();
var formData = $(this).serialize();
var formAction = $(this).attr('action');
$.post(formAction, formData, function(data){
console.log(data);
$("#comments").append(
`<div class="jumbotron comment">
<div class="row">
<div class="col-md-1">
<img class="comment-ico" src = "${data.comment.author.image}">
</div>
<div class="col-md-7">
<h4>${data.comment.author.username}</h4>
</div>
<div class="col-md-4 date">
${data.commentCreated}
</div>
</div>
</div>
<div id="A<%=comment._id%>"><p>${data.comment.text}</p></div>
<form id="edit-comment-form" action = "/blogs/data._id %>/comments" method = "POST" id="newComment">
<textarea class = "form-control" rows="4" placeholder = "Type comment here..." name = "comment[text]"></textarea>
<button class = "btn btn-lg btn-primary btn-block">Submit</button>
</form>
<div class="row" id="B${data.comment._id}">
<div class="col-md-1 choice">
<a class="edit">Edit</a>
</div>
<div class="col-md-1 choice1">
<form id = "delete-form" action = "/blogs/${data.blog._id}/comments/${data.comment._id}?_method=DELETE" method = "POST">
<input type = "submit" class = "button-delete" value = "Delete">
</form>
</div>
</div>
<hr class = "style-three">`
);
$('#newComment').find('.form-control').val('');
});
});
Inject a moment object into your ejs templates that manipulates date objects to display different formats. For example:
var moment = require('moment');
var Blog = require('./models/blog');
exports.index = function(req, res) {
Blog.find().exec(function(err, blogs){
if (err) throw err;
// send moment to your ejs
res.render('index', { moment: moment, blogs: blogs });
});
}
And in your template, use the fromNow() API for displaying the timeago or relative time:
<div id="comments">
<% blog.comments.forEach(function(comment){ %>
<div class="jumbotron comment">
<div class="row">
<div class="col-md-1">
<img class="comment-ico" src = "<%=comment.author.image%>">
</div>
<div class="col-md-7">
<h4><%=comment.author.username%></h4>
</div>
<div class="col-md-4 date">
Created <%= moment(comment.created).fromNow(true) %> ago
</div>
<!--<div class="col-md-4 date">
Created at <%= moment(comment.created).format('Do MMM YYYY') %>
</div>-->
</div>
</div>
<div><p><%=comment.text%></p></div>
Another alternative is to create an ejs filter function that will return fromNow:
JavaScript
var ejs = require('ejs');
var moment = require('moment');
ejs.filters.fromNow = function(date) {
return moment(date).fromNow();
}
Template
<div class="col-md-4 date">
Created <%= comment.created | fromNow %> ago
</div>
Remember to have moment added to your package.json file:
npm install moment
UPDATE
Using your actual code, you only need to use the moment object on the line you create the commentCreated variable:
// create new comment
Comment.create(req.body.comment, function(err, comment){
if(err) {
req.flash("error", "Something went wrong");
console.log(err);
} else {
comment.author.id = req.user._id;
comment.author.username = req.user.username;
comment.author.image = req.user.image;
comment.save();
// connect new comment to campground
blog.comments.push(comment);
blog.save();
var commentCreated = moment(comment.created).fromNow(); // use moment here
if(req.xhr){
res.json({comment: comment, commentCreated: commentCreated, blog: blog});
} else {
// // redirect to campground show page
req.flash("success", "Successfully added comment");
res.redirect("/blogs/" + blog._id);
}
}
});
I have been searching for a long while for solution, but nothing helped me.
I have an Angular JS app which runs with Mongoose and Express.
I want to store date as object from a simple form.
But when I submit my form, dates are stored as String and not as Objects.
So I can't do something like :
tache.start.getDate();
Here is my form :
<form name="formTache" ng-submit="addTache(tache)">
<div class="form-group row">
<div class="col-lg-12">
<input name="name" class="form-control" placeholder="Nom" type="text" ng-model="tache.title"/>
</div>
</div>
<div class="form-group row">
<div class="col-lg-12">
<input id="date" name="date" class="form-control" placeholder="Date" ng-model="tache.start" type="date"/>
</div>
</div>
<div class="form-group row">
<div class="text-right col-lg-12">
<button type="submit" class="btn btn-default">Ajouter</button>
</div>
</div>
Here is my Mongoose Schema :
var restful = require('node-restful');
var mongoose = restful.mongoose;
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var tachesSchema = new mongoose.Schema({
title : String,
start: {type: Date, default: new Date()},
});
var tachesModel = mongoose.model('taches', tachesSchema);
module.exports = restful.model('taches', tachesSchema);
Here is my Controller :
angular.module('personaldashboard.tache', [])
.controller('TachesCtrl', function($scope, Taches, Progress, toaster) {
$scope.tache = new Taches();
var refreshTache = function() {
$scope.taches = Taches.query();
$scope.tache = ''
}
refreshTache();
$scope.addTache = function(tache) {
Taches.save(tache,function(tache){
refreshTache();
});
};
$scope.updateTache = function(tache) {
tache.$update(function(){
refreshTache();
});
};
$scope.removeTache = function(tache) {
tache.$delete(function(){
refreshTache();
});
};
$scope.editTache = function(id) {
$scope.tache = Taches.get({ id: id });
};
$scope.deselectTache = function() {
$scope.tache = ''
}
$scope.editTache_Projet = function(tache, projetId) {
tache.projet = projetId;
tache.$update(function(){
refreshTache();
});
};
});
Here is what I get :
{ "_id": "58a99df24975ad0104c692b1", "title": "Test", "start": "2017-02-24T23:00:00.000Z" }
So why do I get a string like "2017-02-24T23:00:00.000Z" for my date instead of an object whereas my Mongoose schema specify start: {type: Date, default: new Date()} ?
Thanks for your help.
EDIT
Thanks to Saurabh Agrawal, I tried to convert the date when submiting in the controller :
$scope.addTache = function(tache) {
tache.start = new Date(tache.start);
tache.end = new Date(tache.end);
Taches.save(tache,function(tache){
refreshTache();
});
};
Sadly, this changed nothing :(
I still have a date as string
"2017-02-20T23:00:00.000Z"
EDIT
I also tried to add a directive
.directive("formatDate", function(){
return {
scope: {ngModel:'='},
link: function(scope) {
if (scope.ngModel) {
scope.ngModel = new Date(scope.ngModel);
}
}
}
})
and call it in my form
<form name="formTache" ng-submit="addTache(tache)">
<div class="form-group row">
<div class="col-lg-12">
<input name="name" class="form-control" placeholder="Nom" type="text" ng-model="tache.title"/>
</div>
</div>
<div class="form-group row">
<div class="col-lg-12">
<input id="date" name="date" class="form-control" placeholder="Date" ng-model="tache.start" type="date" formatDate/>
</div>
</div>
<div class="form-group row">
<div class="text-right col-lg-12">
<button type="submit" class="btn btn-default">Ajouter</button>
</div>
</div>
But nothing changes.
Any other ideas ?
By searching, I 've found that I was missing the real problem.
My dates are date objects.
When i do this
$scope.test = new Date([2017,2,15]);
<pre>{{test}}</pre>
<pre>{{test.getDate()}}</pre>
I get
"2017-02-14T23:00:00.000Z" and 15
So date displaying like "2017-02-14T23:00:00.000Z" are objects.
But in my case, when i try to do the same with a date whitch is in another object like in this schema :
var tachesSchema = new mongoose.Schema({
title : String,
start: {type: Date, default: new Date()},
end: {type: Date, default: new Date()},
comment : String,
state : Boolean,
projet : { type: ObjectId, ref: 'Projets' }
});
I get nothing :(
This code :
{{tache.start}}
displays the date like this "2017-02-20T23:00:00.000Z"
but
<pre>{{tache.start.getDate()}}</pre>
displays nothing.
What I missed ?
I am attempting to send form data from a page to MongoDB in Node.js.
The issue I am running into is when I am clicking the 'Add Group' button to submit the data.. the page tries to complete the request but seems to get stuck when trying to push the data to the database. So it then is just sitting there, stuck, trying to take the inputted data and place it into the database.
Here is my Group Model:
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
path = require('path');
var GroupsSchema = new Schema({
groupName: {type: String}
});
GroupsSchema.virtual('uniqueId')
.get(function(){
return this.filename.replace(path.extname(this.filename), '');
});
module.exports = mongoose.model('Groups', GroupsSchema);
Here is my Group Controller:
var Models = require('../models');
module.exports = {
index: function(req, res){
var viewModel = {
groups: []
};
Models.Group.find({}, function(err, groups){
if(err){
throw err;
}else{
viewModel.groups = groups;
res.render('addGroup', {title: 'Admin Add Product Group', adminloggedin: true, subtitle: 'Add a Group', underheaderp: ''});
}
});
},
create: function(req, res){
var saveGroup = function(){
Models.Group.find({}, function(err, groups){
if(groups.length > 0){
saveGroup();
}else{
Models.Group.find({},function(err, groups){
if(err){
throw err;
}else{
var newGrp = new Models.Group({
groupName: req.body.groupname
});
newGrp.save(function(err, group){
console.log('Successfully inserted Group');
res.redirect('admin/addGroup');
});
}
});
}
});
};
saveGroup();
}
};
My current Routes:
var express = require('express'),
router = express.Router(),
addGroup = require('../controllers/addGroup');
module.exports = function(app){
router.get('/admin/addGroup', addGroup.index);
router.post('/admin/addGroup', addGroup.create);
app.use(router);
}
And my addGroup handlebars page
<!-- Add a Product Group Form -->
<div class="row">
<div class="col-md-6">
<form action="/admin/addGroup" method="post">
<fieldset class="form-group">
<label for="newGroupName">Group Name:</label>
<input type="text" class="form-control" name="groupname">
</fieldset>
<fieldset class="form-group">
<label for="groupImageFolder">Image Folder Name:</label>
<input type="text" class="form-control" name ="groupImageFolder">
</fieldset>
<button type="submit" class="btn btn-success" type="button">Add Group</button>
</form>
</div>
</div>
Unfortunately, I have yet to find a great way to debug my applications as I am still a new programmer. Any recommendations would be great as well.
The problem must be in my controller :create
Possibly where I am defining my var newGrp and trying to set it to my group models?
How can I fix this to make it so it saves the inputted data to MongoDB?
Any help is greatly appreciated.