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("/");
}
});
}
Related
Any help appreciated. I've got an app that pulls data from google books api. From each book page, the user is able to leave a review. The path to the review is /review/${isbn Number}. Each page has a path based on the isbn. The review routes work and I'm able to make the post request through insomnia/postman with no issues, I'm just having trouble with the front-end js in pulling the data from the input boxes to make the post request. I'm not sure if the issue is because the isbn being in the path. Below is my front-end javascript that I am unable to fix.
const newFormHandler = async (event) => {
event.preventDefault();
console.log("testing")
const description = document.querySelector('#description').value;
const reviewTitle = document.querySelector('#reviewTitle').value;
const isbn = window.location.search
if (description) {
const response = await fetch(`api/review/${isbn}`, {
method: 'POST',
body: JSON.stringify({ description, reviewTitle }),
headers: {
'Content-Type': 'application/json',
},
});
if (response.ok) {
document.location.reload();
} else {
alert('Failed to create review');
}
}
};
document
.querySelector('.form-group')
.addEventListener('submit', newFormHandler);
My form is below:
<div class="col form-group">
<div class ="card reviewCard" style = "background-color:#fcf8f3; color: #65625e;">
<form id="blog-form">
<div>
<label for="reviewTitle">Review Title</label>
<input
value="{{title}}"
id="reviewTitle"
name="reviewtitle"
placeholder="Enter Review Title"
type="text"
required="required"
class="form-control"
data-bv-notempty="true"
data-bv-notempty-message="The title cannot be empty"
/>
</div>
<div>
<label for="review">Review</label>
<textarea
id="description"
name="review"
cols="40"
rows="10"
required="required"
class="form-control"
>{{description}}</textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</div>
</div>
And here is my route that works fine with insomnia, no issues.
router.get('/review/:id', async (req, res) => {
try {
const isbn13 = req.params['id'];
const reviewData = await Review.findAll({ where: {
isbn:isbn13
},
include: [
{
model: User,
attributes: ['name'],
}
]
})
const reviews = reviewData.map((review) => review.get({ plain:true}));
// console.log(isbn13);
res.render('review', {
isbn: isbn13, reviews:reviews
});
} catch (err) {
console.log(err)
}
});
Any help appreciated. I tried to pull in the isbn number from the path, but with no success. I think I have it formatted wrong somehow.
First console log your req
You should see the body containing some data.
In a get request the they are arguments in the URL.
In a Psot request they are in the body of the request.
I'm trying to make a simple blog app using NodeJS, MongoDB and Express. My goal here is to be able to have the user write a title and text, have it go to my MongoDB database and have it show in a new, redirected page according to the ID of the new submission. However this is not working, the page will redirect and show "Cannot GET /users/postpage/(ID here)"
Here are my file paths:
config -->
|auth.js
|keys.js
|passport.js
models -->
|Createpost.js
|User.js
routes -->
|index.js
|users.js
views -->
dashboard.ejs
postpage.ejs
app.js
My code in Createpost.js:
const TextSchema = new mongoose.Schema({
postTitle: {
type: String,
required: true
},
postText: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
const Createpost = mongoose.model('Createpost', TextSchema);
My code in users.js:
router.get('postpage/:/id', (req,res)=>{
res.send(req.params.id)
})
router.post('/postpage', async (req,res)=> {
let newPost = new Createpost({
postTitle:req.body.postTitle,
postText:req.body.postText
})
try {
newPost = await newPost.save()
res.redirect(`/users/postpage/${newPost.id}`)
} catch (error){
console.log(error)
res.render('users/postpage', {newPost:newPost})
}
})
My code in postpage.ejs:
<form action="/users/postpage" method="POST">
<div class="form-group">
<label for="postTitle">Title</label>
<input required
type="postTitle"
id="postTitle"
name="postTitle"
class="form-control"
placeholder="Enter title"
value="<%= typeof postTitle != 'undefined' ? postTitle : '' %>"
/>
</div>
<div class="form-group">
<label for="postText">text</label>
<input required
type="postText"
id="postText"
name="postText"
class="form-control"
placeholder="Enter text"
value="<%= typeof postText != 'undefined' ? postText : '' %>"
/>
</div>
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!'});
});
});
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.
I have been trying to set up nodemailer with my static site. I am having trouble getting require to work at the moment. I know I am doing something wrong - I just need another set of eyes to assist.
HTML:
<form name="betaForm" action="/betaForm" method="post">
<div class="form-group" >
<label for="contactName" style="float:left;">Contact Name</label>
<input type="test" name="contactName" value="" class="form-control" id="contactName" >
</div>
<div class="form-group">
<label for="practiceName" style="float:left;">Practice Name</label>
<input type="test" name="practiceName" value="" class="form-control" id="practiceName">
</div>
<div class="form-group">
<label for="phone1" style="float:left;">Phone</label>
<input type="test" name="phone1" value="" class="form-control" id="phone1">
</div>
<div class="form-group">
<label for="email1" style="float:left;">Email</label>
<input type="email" name="email1" value="" class="form-control" id="email1" >
</div>
<button type="submit" value="Send" class="btn btn-default">Submit</button>
</form>
SERVER.JS
var express=require('express');
var nodemailer = require("nodemailer");
var app = express();
app.get('/',function(req,res){
res.sendfile('www/index.html');
});
app.listen(3000,function(){
console.log("Express Started on Port 3000");
});
SENDMAIL.JS
var app = require('express');
var nodemailer = require('nodemailer');
app.get('/betaForm', routes.betaForm);
app.post('/betaForm', function (req, res) {
var mailOpts, smtpTrans;
//Setup Nodemailer transport, I chose gmail. Create an application-specific password to avoid problems.
smtpTrans = nodemailer.createTransport('SMTP', {
service: 'Gmail',
auth: {
user: "test#gmail.com",
pass: "password"
}
});
//Mail options
mailOpts = {
from: req.body.contactName + ' <' + req.body.email1 + '>', //grab form data from the request body object
to: 'test#gmail.com',
subject: ' beta contact form',
text: req.body.contactName,
};
smtpTrans.sendMail(mailOpts, function (error, response) {
//Email not sent
if (error) {
res.render('betaForm', { title: ' beta contact', msg: 'Error occured, message not sent.', err: true, page: 'contact' })
}
//Yay!! Email sent
else {
res.render('betaForm', { title: ' beta contact', msg: 'Message sent! Thank you.', err: false, page: 'contact' })
}
});
});
ROUTES.JS
var exports = module.exports = {};
exports.betaForm = function(req, res){
res.render('betaForm', { title: 'beta contact form', page: '/#beta' })
};
Sorry I'm not allowed to write comments.
Do you use the bodyparser?