I trying to make a survey website and I have been stuck on this bug for hours. I have a from that has 5 inputs and it takes name, question and 4 options as text and submits them. when clicking on submit button the server recieves a post method with the action /all after getting /all the server should render all.ejs. below is my index.js file:
router.post('/all', function (req, res) {
const newsurvey=new survey({
"name":req.body.name,
"question":req.body.question,
"option1":req.body.option1,
"option2": req.body.option2,
"option3":req.body.option3,
"option4": req.body.option4,
})
survey.create(newsurvey)
console.log(newsurvey)
console.log(req.body.name)
res.render('all', { title: 'All Surveys', survey});
});
// initializing a new survey object
router.get('/addsurvey', function (req, res, next) {
survey.find((err, list)=>{
const newsurvey = new survey({
"name":"",
"question":"",
"option1":"",
"option2":"",
"option3":"",
"option4":""
}
)}
,res.render('surdetails', { title: 'Details', survey})
);
});
router.get('/all', function (req, res) {
survey.find((err, list)=>{
if (err){
return console.error(err);
}else{
res.render('all', { title: 'All Surveys', survey: survey });
}
})
});
and below is my all.ejs file which returns cannot read properties of undefined(reading"name"):
<tbody>
<!-- Template Row -->
<% for (let count = 0; count < survey.length; count++) { %>
<tr>
<td><%= survey[count].name %></td>
<td class="text-center"><%= survey[count].name %></td>
<td class="text-center"><%= survey[count].question %></td>
<td class="text-center">
<input type="radio" id="option1" name="option1" value="<%= survey[count].option1 %>">
<label for="option1"><%= survey[count].option1 %></label><br>
<input type="radio" id="option2" name="option2" value="<%= survey[count].option2 %>">
<label for="option2"><%= survey[count].option2 %></label><br>
<input type="radio" id="option3" name="option3" value="<%= survey[count].option3 %>">
<label for="option3"><%= survey[count].option3 %></label><br><br>
</td>
<td class="text-center">
<i class="fa fa-trash-o"></i> Delete
</td>
</tr>
<% } %>
</tbody>
Related
I have an app, it uses an external api for data
http://newsapi.org/v2/top-headlines?category=alpha&apiKey=APIKEY
this external API shows data for several categories:
http://newsapi.org/v2/top-headlines?category=beta&apiKey=APIKEY
http://newsapi.org/v2/top-headlines?category=gamma&apiKey=APIKEY
http://newsapi.org/v2/top-headlines?category=theta&apiKey=APIKEY
My app has user login and select which category they prefer. Its a multiselect control.
Based on the selection of the categories, I need to show data from those.
Eg: if user selected alpha and beta and save it. Then the homepage should show NEWS from those two categories only in one list
I am using Node JS Express and Mongo with vanilla JS
Following is some code I wrote, but unable to make it work.
index.js
router.get('/homepage', auth, async(req,res)=>{
const alpha= req.user.alpha
const beta = req.user.beta
const gamma= req.user.gamma
const theta= req.user.theta
if (alpha== 'yes'){
var url = 'http://newsapi.org/v2/top-headlines?category=alpha&apiKey=APIKEY';
const news_alpha =await axios.get(url)
}
if (beta == 'yes'){
var url = 'http://newsapi.org/v2/top-headlines?category=beta&apiKey=APIKEY';
const news_beta =await axios.get(url)
}
if (gamma== 'yes'){
var url = 'http://newsapi.org/v2/top-headlines?category=gamma&apiKey=APIKEY';
const news_gamma =await axios.get(url)
}
if (theta== 'yes'){
var url = 'http://newsapi.org/v2/top-headlines?category=theta&apiKey=APIKEY';
const news_theta =await axios.get(url)
}
//HERE I AM TRYING TO SEND ALL VALID CATEGORIES DATA TO UI. NOT SURE IF ITS RIGHT WAY TO DO!
try {
res.status(200).render('home',{articles:news_alpha.data.articles, articles:news_beta.data.articles, articles:news_gamma.data.articles, articles:news_theta.data.articles, user: req.user, id: req.user._id})
} catch (error) {
if(error.response){
console.log(error)
}
}
});
homepage.ejs
<div >
<% articles.forEach(function(article,index){ %>
<% if ((typeof article.url=='object') || (typeof article.title=='object') || (typeof article.urlToImage=='object') || (typeof article.content=='object')){ %>
<% } else{ %>
<a href="<%- article.url %>" target="_blank" class="news-box Hover-effect">
<!-- <img src="<%- article.urlToImage %>" alt="Image"> -->
<h3>
<%- article.title %>
</h3>
<p>
<%- article.content.replace(/<[^>]+>/g, '') %>
</p>
<br>
</a>
<% } %>
<% }) %>
</div>
PAGE WHERE USER SELECTS THEIR PREFERENCES OF CATEGORIES
they are basically radio button with YES / NO
<body>
<div>
<form method="PUT" id="update_user" action="/homepage">
<div class="form-group">
<h3> <label for="name" class="text-dark">preferences</label> </h3>
<input type="hidden" name="id" value="<%= id %>">
</div>
<div class="form-group">
<label for="alpha" class="text-dark">alpha</label>
<input type="radio" id="radio-2" name="alpha" value="yes" <%= alpha== 'yes' ? 'checked' : '' %>>
<label for="radio-2" class="radio-label">Yes</label>
<input type="radio" id="radio-3" name="alpha" value="no" <%= alpha== 'no' ? 'checked' : '' %> >
<label for="radio-3" class="radio-label">No</label>
</div>
<div class="form-group">
<label for="beta" class="text-dark">beta</label>
<input type="radio" id="radio-2" name="beta" value="yes" <%= beta== 'yes' ? 'checked' : '' %>>
<label for="radio-2" class="radio-label">Yes</label>
<input type="radio" id="radio-3" name="beta" value="no" <%= beta== 'no' ? 'checked' : '' %> >
<label for="radio-3" class="radio-label">No</label>
</div>
<div class="form-group">
<label for="gamma" class="text-dark">gamma</label>
<input type="radio" id="radio-2" name="gamma" value="yes" <%= gamma== 'yes' ? 'checked' : '' %>>
<label for="radio-2" class="radio-label">Yes</label>
<input type="radio" id="radio-3" name="gamma" value="no" <%= gamma== 'no' ? 'checked' : '' %> >
<label for="radio-3" class="radio-label">No</label>
</div>
<div class="form-group">
<label for="theta" class="text-dark">theta</label>
<input type="radio" id="radio-2" name="theta" value="yes" <%= theta== 'yes' ? 'checked' : '' %>>
<label for="radio-2" class="radio-label">Yes</label>
<input type="radio" id="radio-3" name="theta" value="no" <%= theta== 'no' ? 'checked' : '' %> >
<label for="radio-3" class="radio-label">No</label>
</div>
So to summarise, the objective is user selects categories, one or few or all from preferences.
Based on each preference there are some news articles linked in external API
therefore I need to bring all the news articles for the preferences marked as YES, consolidate the response and send to UI for display.
Can you guys help me? Please let me know!
I got this error
CastError: Cast to ObjectId failed for value "details5f9c3b069dc8723528c64cc8" at path "_id" for model "Book"
the edit and delete button are not activated.
Help me to figure it out please. this is /routes/books.js
and what else do I upload here?
// GET edit an existing Book
router.get('/:id', (req, res, next) => {
let id = req.params.id;
book.findById(id, (err, bookToEdit) => {
if(err) {
console.log(err);
//res.end(err);
} else {
//show the edit view
res.render('books/details', {title: 'Edit Book', books: bookToEdit})
}
});
});
// POST and update the document
router.post('/:id', (req, res, next) => {
let id = req.params.id
let updatedBook = book({
_id: id,
title: req.body.title,
description: req.body.description,
price: req.body.price,
author: req.body.author,
genre: req.body.genre
});
book.updateOne({_id: id}, updatedBook, (err) => {
if(err) {
console.log(err);
res.end(err);
} else {
// refresh
res.redirect('/books');
}
});
});
// GET - process the delete by user id
router.get('/delete/:id', (req, res, next) => {
let id = req.params.id;
book.remove({_id: id}, (err) => {
if(err) {
console.log(err);
res.end(err);
} else {
// refresh
res.redirect('/books');
}
});
});
This is /books/details.ejs
<div class="container">
<div class="row">
<form class="form" method="post">
<div class="form-group">
<label for="TitleTextField">Title</label>
<input type="text" class="form-control" id="TitleTextField"
placeholder="Book Title" name="title" value="<%= books.Title %>" required>
</div>
<div class="form-group">
<label for="AuthorTextField">Author</label>
<input type="text" class="form-control" id="AuthorTextField"
placeholder="Book Author" name="author" value="<%= books.Author %>" required>
</div>
<div class="form-group">
<label for="PriceTextField">Price</label>
<input type="text" class="form-control" id="PriceTextField"
placeholder="Book Price" name="price" value="<%= books.Price %>" required>
</div>
</div>
</div>
and this is /books/indexejs
<% include ../partials/header.ejs %>
<!-- MAIN CONTENT -->
<div class="container">
<div class="row">
<!--Add-->
<i class="fa fa-plus"></i> Add a book
<br>
<br>
<div class="table-responsive">
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>Title</th>
<th class="text-center">Author</th>
<th class ="col-4">Price</th>
<th class="text-center">EDIT</th>
<th class="text-center">DELETE</th>
</tr>
</thead>
<tbody>
<% for (let count = 0; count < books.length; count++) { %>
<tr>
<td><%= books[count].Title %></td>
<td class="text-center"><%= books[count].Author %></td>
<td class="text-center">$<%= books[count].Price %></td>
<!--EDIT-->
</td>
<td class="text-center">
<a href="/books/edit<%= books[count].id %>" class="btn btn-primary btn-sm">
<i class="fas fa-pencil-alt"></i> Edit</a>
</td>
<!--DELETE-->
<td class="text-center">
<a href="/books/delete<%= books[count].id %>" class="btn btn-danger btn-sm">
<i class="fas fa-trash-alt"></i> Delete</a></td>
</td>
</tr>
<% } %>
</tbody>
</table>
</div>
</div>
</div>
</div>
<% include ../partials/footer.ejs %>
this is /models/books.js
let mongoose = require('mongoose');
let Book = mongoose.Schema({
Title: String,
Description: String,
Price: Number,
Author: String,
Genre: String
},
{
collection: "books"
});
module.exports = mongoose.model('Book', Book);
hope these are helpful to fix the problems
You have an error that said that book.find and book.delete need an ObjectId as parameter. And details5f9c3b069dc8723528c64cc8 is not a valid ObjectId for Mongo.
Just read the error message !
Edition
Maybe you face this problem because you made a little mistake with resources, using same http POST to create and edit, giving the :id in path in both case.
If you have a POST / (no id in path) method to create books, letting mongodb generate ids, and have a PATCH (or PUT) /:id method to update those books, you probably will not have this kind of error anymore.
It will maybe sounds like stupid duplication but as your app will grow, you certainly will need to add some specific security rules.
Also, if I remember mongoose correctly, you're not supposed update the _id in second parameter for updateOne.
//no _id present in updatedBook
book.updateOne({_id: id}, updatedBook, (err) => { };
The default key of a document in MongoDB is _id who set an ObjectId in it.
ObjectId is a unique key who contained from some meaningful base on date and time (you can convert objectId to date).
You can read more about it here.
And your problem, it's really easy. You concat your ObjectId with details as you can see in the error.
details5f9c3b069dc8723528c64cc8 => 5f9c3b069dc8723528c64cc8
I'm relatively new to node and express, and have come across a problem I can't seem to solve.
So I came across with the problem trying to validate a create product form, that when I introduce correct values into the fields express-validator throws error.
This is my routes code:
router.post('/create', [
check('name').isLength({ min: 5 }).withMessage("Invalid Value"),
check('description').isLength({ min: 20 }).withMessage("Invalid Value")
] , upload.any() , productosController.guardarCreado);
This is my productosController code:
guardarCreado: (req, res, next) => {
let errors = validationResult(req);
if(errors.isEmpty()){
db.Product.create({
name: req.body.nombre,
description: req.body.descripcion,
size: req.body.talle,
price: req.body.precio,
category_id: 2,
img_url: req.files[0].filename
})
res.redirect('/productos');
}else{
db.Category.findAll()
.then(function(categorias){
return res.render('crearProductos', { categorias: categorias, errors: errors.errors });
})
}
}
And my form code is from Bootstrap and the names of the form fields are the same as the names on the 'check' from my routes code:
<div class="col-md-3 mb-3">
<label for="validationDefault03">Nombre del Producto</label>
<input name="name" id="nombre" type="text" class="form-control" placeholder="Ej: Remera River Plate" >
</div>
<div class="col-12">
<label for="description" class="form-label">Descipción:</label><br>
<textarea name="description" id="description" class="form-input"></textarea>
</div>
Error display on the the form via EJS:
<% if (typeof errors != 'undefined') { %>
<p style= "color: red">ERROR</p>
</div>
<ul>
<% for(let i = 0; i < errors.length; i++) { %>
<li>
<%= errors[i].msg %>
</li>
<% } %>
</ul>
<% } %>
I have written a code where I want the admin to be able to change the user as active or inactive through radio button. For that I am using JSP, MySQL and JS.
admin.jsp:
<tr>
<td>
Name: <% out.println(firstname); %> <% out.println(lastname); %>
</td>
<td>
<% if (flag.equals("A")){ %>
Active: <input type="radio" value="A" name="<% out.println(email); %>" id="<% out.println(email); %>" onchange="pageupdatecta('<% out.println(email); %>', this.value);" checked>
Inactive: <input type="radio" value="I" name="<% out.println(email); %>" id="<% out.println(email); %>" onchange="pageupdatecti('<% out.println(email); %>', this.value);">
<%
}else if(flag.equals("I")){%>
Active: <input type="radio" value="A" name="<% out.println(email); %>" id="<% out.println(email); %>" onchange="pageupdatecta('<% out.println(email); %>', this.value);">
Inactive: <input type="radio" value="I" name="<% out.println(email); %>" id="<% out.println(email); %>" onchange="pageupdatecti('<% out.println(email); %>', this.value);" checked>
<%
} %>
<script type="text/javascript">
function pageupdatecta(emailid, optedval) {
location.href='changeToActive.jsp?email='+emailid+'&optedval='+optedval;
}
function pageupdatecti(emailid, optedval) {
location.href='changeToInactive.jsp?email='+emailid+'&optedval='+optedval;
}
</script>
changeToActive.jsp:
try{
Class.forName("com.mysql.jdbc.Driver");
System.err.println("Driver loaded!");
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost/work", "root", "MyNewPass");
System.err.println("Database Connected..");
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
stmt.executeUpdate("update assignment set flag='A' where email='"+email+"'");
System.err.println("A"+email);
}
Can you tell me how to receive values from the function, and make my code work?
The below code will fetch a record from assignment table of work database for id=1.
The checked status of the radio button will be decided by the existing checked status in the DB.
Here, as soon as you change the status from active to inactive OR inactive to active the changes will be reflected successfully in the database.
index.jsp Page:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" %>
<%# page import="java.sql.*,stack.filter.JDBCConnector" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Radio Select</title>
</head>
<body>
<%
Connection con = null;
String firstname = null;
String lastname = null;
String email = null;
String flag = null;
try {
con = JDBCConnector.connect_database();
Statement stmt = con.createStatement();
ResultSet rs=stmt.executeQuery("select * from assignment where id=1");
while(rs.next()){
firstname=rs.getString(2);
lastname=rs.getString(3);
email=rs.getString(4);
flag=rs.getString(5);
}
System.out.println(""+firstname+" "+lastname+" "+email+" "+flag);
} catch (Exception e) {
e.printStackTrace();
} finally {
con.close();
}
%>
<table>
<tr>
<td>
Name: <% out.println(firstname); %> <% out.println(lastname); %>
</td>
<td>
<%
if(flag.equals("A")){
%> Active: <input type="radio" name="<%=email%>" id="r1" value="A" onclick="updateStatus()" checked="checked"/>
In active: <input type="radio" name="<%=email%>" id="r2" value="I" onclick="updateStatus()"/>
<%
}else if(flag.equals("I")){
%> Active: <input type="radio" name="<%=email%>" id="r1" value="A" onclick="updateStatus()"/>
In active: <input type="radio" name="<%=email%>" id="r2" value="I" onclick="updateStatus()" checked="checked"/>
<%
}
%>
</td>
</tr>
</table>
<script type="text/javascript">
function updateStatus(){
if (document.getElementById('r1').checked) {
location.href='changeToActive.jsp?email='+'${email}'+'&status=A';
}else if (document.getElementById('r2').checked) {
location.href='changeToActive.jsp?email='+'${email}'+'&status=I';
}
}
</script>
</body>
</html>
changeToActive.jsp:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# page import="java.sql.*,stack.filter.JDBCConnector" %>
<%
Connection con = null;
try {
con = JDBCConnector.connect_database();
System.err.println("Database Connected..");
Statement stmt = con.createStatement();
String status = request.getParameter("status");
String email = request.getParameter("email");
int i= stmt.executeUpdate("UPDATE assignment SET status='"+status+"' where email='"+email+"'");
if(i==1){
out.println("Successfully updated the status");
}
} catch (Exception e) {
e.printStackTrace();
}finally{
con.close();
}
%>
JDBCConnector.java class: created for centrally creating connection object in your app.
package stack.filter;
import java.sql.Connection;
import java.sql.DriverManager;
public class JDBCConnector {
public static Connection connect_database(){
Connection con = null;
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost/work", "root", "root");
} catch (Exception e) {
e.printStackTrace();
} finally {
if(con!=null)
{
System.out.println("Connected...");
}
}
return con;
}
}
Assignment Table:
CREATE TABLE `assignment` (
`id` INT(11) NOT NULL,
`firstname` VARCHAR(30) DEFAULT NULL,
`lastname` VARCHAR(30) DEFAULT NULL,
`email` VARCHAR(30) DEFAULT NULL,
`status` CHAR(1) DEFAULT NULL,
PRIMARY KEY (`id`)
)
/*Data for the table `assignment` */
INSERT INTO `assignment`(`id`,`firstname`,`lastname`,`email`,`status`) VALUES (1,'rohit','gaikwad','rohitgaikwad#xyz.com','I');
Note: The id=1 primary key is hardcoded, I guess you have some logic that displays a record of assignment in your html table.
You can get the values of query parameters with:
String email = request.getParameter("email");
String optedval = request.getParameter("optedval");
Then you can use them in your sql statement.
It should be like this. You have given same id to both the radio.
Active: <input type="radio" value="A" name="<% out.println(email); %>" id="id1" onchange="pageupdatecta('<% out.println(email); %>');" checked>
Inactive: <input type="radio" value="I" name="<% out.println(email); %>" id="id2" onchange="pageupdatecti('<% out.println(email); %>');">
<script>
function pageupdatecta(emailid) {
alert('Hi');
location.href='changeToActive.jsp?email='+emailid;
}
function pageupdatecti(emailid) {
alert('Hi');
location.href='changeToActive.jsp?email='+emailid;
}
</script>
and in your servlet use String email = request.getParameter("email");to get the value of email variable.
I would like to form data parameter correctly inside ajax call.
<script type="text/javascript">
$(document).ready(function() {
$('#call').click(function ()
{
$.ajax({
type: "post",
url: "books", //this is my servlet
data: <<< my data here >>>
});
});
});
</script>
This is part of my jsp:
<form action="books" method="post">
<table width="70%" border="1">
<%
List<Book> books = (List<Book>) request.getAttribute("books");
for (int i = 0; i < books.size(); i++) {
%>
<tr>
<td>
<input type="checkbox" name="book<%=i%>"
value="<%= books.get(i).getBook_id()%>"> <%= books.get(i).getName() %>
</td>
</tr>
<%
}
%>
</table>
<select name="user_name">
<%
List<User> users = (List<User>) request.getAttribute("users");
for (int i = 0; i < users.size(); i++) {
%>
<option value="<%=users.get(i).getName()%>"><%=users.get(i).getName()%></option>
<%
}
%>
</select>
<input type="submit" name="submit" value="Purchase">
<input type="button" value="Call Servlet" name="Call Servlet" id="call"/>
</form>
I would like to pass everything that normally passes by form above.
Could you please show me around ajax technology by this example?
Give an instance id to the form and use with the serialize() method
$('#form').submit(function ()
{
$.ajax({
type: "post",
url: "books", //this is my servlet
data: $(this).serialize()
});
});
<form id="form" action="books" method="post">
<table width="70%" border="1">
<%
List<Book> books = (List<Book>) request.getAttribute("books");
for (int i = 0; i < books.size(); i++) {
%>
<tr>
<td>
<input type="checkbox" name="book<%=i%>"
value="<%= books.get(i).getBook_id()%>"> <%= books.get(i).getName() %>
</td>
</tr>
<%
}
%>
</table>
<select name="user_name">
<%
List<User> users = (List<User>) request.getAttribute("users");
for (int i = 0; i < users.size(); i++) {
%>
<option value="<%=users.get(i).getName()%>"><%=users.get(i).getName()%></option>
<%
}
%>
</select>
<input type="submit" name="submit" value="Purchase">
<input type="button" value="Call Servlet" name="Call Servlet" id="call"/>
</form>