How do I get my server.js to access redux values? - node.js

I have a checkout page for a store that has some inputs such as address, name, etc. I also want to upload the cart info to the mongodb as well, but it's not working. The cart info comes from redux using the useSelector from redux, but I can't put that function into server.js. Does anyone have any tips? I have provided the schema below as well.
Server.js
require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const connectDB = require('./config/db');
const productRoutes = require('./routes/productRoutes');
const CustomerInfo = require("./models/customerInfo");
connectDB();
const app = express();
app.use(express.json());
app.use('/api/products', productRoutes);
const PORT = process.env.PORT || 5000;
app.use(bodyParser.urlencoded({extended: true}));
//app.post
app.post ("/", function(req, res) {
let newCustomerInfo = new CustomerInfo({
fname: req.body.firstName,
lname: req.body.lastName,
email: req.body.email,
phone: req.body.phoneNumber,
address: req.body.address,
city: req.body.city,
district: req.body.district,
section: req.body.section,
confirmCode: req.body.confirmCode,
comments: req.body.extraInfo,
cartItems: req.body.cartcount
});
newCustomerInfo.save();
res.redirect("/");
})
app.listen(PORT, () => console.log(`Server Running on port ${PORT}`))
CheckoutScreen.js
import './CheckoutScreen.css';
import { useDispatch, useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
// Components
import CartItem from '../components/CartItem';
const CheckoutScreen = () => {
const cart = useSelector(state => state.cart);
const { cartItems } = cart;
const getCartCount = () => {
return cartItems.reduce((qty, item) => Number(item.qty) + qty, 0)
};
const getCartSubTotal = () => {
return cartItems.reduce((price, item) => item.price * item.qty + price, 0)
};
return (
<div className="checkoutscreen">
<div className="checkout__left">
<body>
<form className="checkout-form" method="post" action="/">
<label className="input">
<input type="text" name="firstName" required/>
<span className="placeholder">First Name</span>
</label>
<label className="input">
<input type="text" name="lastName" required/>
<span className="placeholder">Last Name</span>
</label>
<label className="input">
<input type="text" name="email" required/>
<span className="placeholder">Email</span>
</label>
<label className="input">
<input type="text" name="phoneNumber" required/>
<span className="placeholder">Phone Number</span>
</label>
<label className="input">
<input type="text" name="address" required/>
<span className="placeholder">Address</span>
</label>
<label className="input">
<input type="text" name="city" required/>
<span className="placeholder">City</span>
</label>
<label className="input">
<input type="text" name="district" required/>
<span className="placeholder">District</span>
</label>
<label className="input">
<input type="text" name="section" required/>
<span className="placeholder">Section</span>
</label>
<label className="input">
<input type="text" name="confirmCode" required/>
<span className="placeholder">Confirmation Code</span>
</label>
<label className="input">
<input type="text" name="extraInfo" required/>
<span className="placeholder">Details/Comments</span>
</label>
<p className="cartcount">{getCartCount()}</p>
<button>Submit</button>
</form>
</body>
</div>
<div className ="checkout__right">
<div className="checkout__info">
<p>Subtotal ({getCartCount()}) items</p>
<p>${getCartSubTotal().toFixed(2)}</p>
</div>
</div>
</div>
)
};
export default CheckoutScreen;
customerInfo.js
const mongoose = require("mongoose");
const customerInfoSchema = new mongoose.Schema ({
fname: {
type: String,
required: true
},
lname: {
type: String,
required: true
},
email: {
type: String,
required: true
},
phone: {
type: String,
required: true
},
address: {
type: String,
required: true
},
city: {
type: String,
required: true
},
district: {
type: String,
required: true
},
section: {
type: String,
required: true
},
confirmCode: {
type: String,
required: true
},
comments: {
type: String,
required: false
},
cartItems: {
type: Number,
required: true
}
});
const customerInfo = mongoose.model('Customer Info', customerInfoSchema);
module.exports = customerInfo;

You need to call your API in Server.js. To call the API you need to submit the form and handle the form submission by handleSubmit method on form onSubmit event. In handleSubmit method you need to call checkout action and pass the cart object. The CheckoutAction need to use redux-thunk to call server api asynchronously (side effect with middleware). Once the response back you can return the state by dispatching to CheckoutReducer
CheckoutScreen.js
import { Checkout } from '../action/checkoutAction'
const dispatch = useDispatch();
...........
const handleCheckout = e => {
e.preventDefault();
dispatch(Checkout({ type:'CHECKOUT', payload:cart }));
}
......
<form className="checkout-form" method="post" action="/" onSubmit={e => handleCheckout(e)}>
CheckoutAction.js
export const Checkout = data => async dispatch => {
let response = await axios.post(server_api_url, data);
dispatch({ type: 'checkout_success', payload:response.data}); //to checkout reducer
}

Related

why is my form not post after using post method?

am new to nodeJS am trying to post the collection when the button is been clicked, i don't is posting because am getting an error:undefined, when i console the req.body please what am doing wrong here. is there something am not doing
Here's my code.
//create.ejs file
<form action="/blogs" method="post">
<div>
<label>Title</label>
<input name="title" type="text"/>
</div>
<div>
<label>Content header</label>
<input name="content" type="text"/>
</div>
<div>
<label>Content Body</label>
<textarea name="body"></textarea>
</div>
<div class="button">
<button>Post content</button>
</div>
</form>
//app.js file
const express = require("express")
const app = express()
const mongoose = require("mongoose")
const Schema = mongoose.Schema;
const BlogPost = new Schema({
title:{
type: String,
required: true
},
content: {
type: String,
required: true
},
body: {
type: String,
required: true
}
})
const Blog = mongoose.model("Blog", BlogPost)
module.exports = Blog;
app.post("/blogs", (req, res) => {
const blogs = new Blog({
title:req.body.title,
content: req.body.content,
body: req.body.body,
})
blogs.save()
.then(result => console.log(result))
.catch(err => console.log(err))
})
You must write
<input type="submit" name="Post content" value="Post content">
instead of this Post content
In the button element add
<button type="submit">Post content</button>
I forget to add urlencoded method.
app.use(express.urlencoded({ extended: true }))

how to fix this error ""name":"ValidatorError","message":"Path `Name` is required.""

I am trying to fetch data from client side when i make a post request I get this error , I am new to the mongoDB and Node.js please help
I don't understand this error that why this is coming please help to resolve it
this is my schema code
`
import mongoose from "mongoose";
const signupTemplate = mongoose.Schema({
Name: {
type: String,
required: true,
},
Phone: {
type: Number,
required: true,
},
Email: {
type: String,
required: true,
},
Password: {
type: String,
required: true,
},
date: {
type: Date,
Default: Date.now,
},
});
export default mongoose.model("users", signupTemplate);
`
this is my router code
`
router.post("/signup", (req, res) => {
const signedUpUser = new signUpTemplate({
Name: req.body.Name,
Phone: req.body.Phone,
Email: req.body.Email,
Password: req.body.Password,
});
console.log(req.body.Name);
signedUpUser
.save()
.then((data) => {
res.json(data);
})
.catch((err) => {
res.json(err);
// console.log('you made an error');
});
// res.send("User Registered successfully");
});
`
this is my form code
`
<form action="/signup" method="post">
<label for="Name">Full Name</label>
<input type="text" class="form-control" id="Name" name="Name" />
<label for="Phoneno">Phone No.</label>
<input type="text" class="form-control"id="Phoneno" name="Phone" />
<label for="Email">Email</label>
<input type="email" class="form-control"id="Email" name="Email" />
<label for="create-password">Create Password</label>
<input type="password" class="form-control"id="create-password" name="Password" />
<label for="confirm-password">Confirm Password</label>
<input type="password" class="form-control"id="confirm-password" name=" Confirm-password" />
<button type="submit" class="btn">Sign Up</button>
<hr>
<p style="display:inline;">Or continue with</p>
<i class="fa-brands fa-google"></i>
<i class="fa-brands fa-facebook"></i>
<i class="fa-brands fa-instagram"></i>
</form>
`
Hey do you have the express urlencoded middleware in your index.js or server.js and if not add this line of code
app.use(express.urlencoded({ extended: true }));

I'm trying to add users to my MongoDB database

I want to add a user to my database. But I couldn't add a user.I played on the user schema as much as I could, but I still couldn't get a record in the database. What should I do?
//routes/user.js
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const config = require('config');
const User=require('../models');
const { check, validationResult } = require('express-validator');
const User = require('../models/User');
// #route POST api/users
// #dsc Register a user
// #access Public
router.post(
'/',
[
check('name', 'Please add a name').notEmpty(),
check('email', 'Please include a valid email').isEmail(),
check(
'password',
'Please Enter a password for 6 or more characters'
).isLength({ min: 6 }),
check('address', 'Please include a valid address').notEmpty(),
check('location', 'Please include a valid location').notEmpty(),
check('phone', 'Please include a valid number').isLength(10),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { name, email, password, address, location, phone } = req.body;
try {
let user = await User.findOne({ email });
if (user) {
return res.status(400).json({ msg: 'User already exists' });
}
user = new User({
name,
email,
password,
address,
location,
phone,
});
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
const payload = {
user: {
id: user.id,
},
};
jwt.sign(
payload,
config.get('jwtSecret'),
{
expiresIn: 3600000,
},
(err, token) => {
if (err) throw err;
res.json({ token: token, userId: user.id }rot);
}
);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
}
);
module.exports = router;
//frontend user.js
import React, { Component } from "react";
import { Redirect, Link } from "react-router-dom";
import Home from "./Home";
import "./signup.css";
import img from "./cart-removebg-preview.png";
import img1 from './WhatsApp Image 2020-09-18 at 17.35.32.jpeg';
import Axios from "axios";
import { localsName } from "ejs";
class Signup extends Component {
constructor(props) {
super(props);
this.signup = this.signup.bind(this);
this.handleChange = this.handleChange.bind(this);
this.state = {
email: "",
password: "",
name: "",
phone: "",
address: "",
location: "",
valid: false,
userId: "",
};
}
signup = async (e) => {
e.preventDefault();
await Axios.post("/api/users", {
name: this.state.name,
email: this.state.email,
password: this.state.password,
address: this.state.address,
location: this.state.location,
phone: this.state.phone,
})
.then((res) =>
this.setState({ valid: res.data.token, userId: res.data.userId })
)
.catch((err) => console.log(err));
};
handleChange(e) {
this.setState({
[e.target.name]: e.target.value,
});
}
render() {
if (this.state.valid) {
localStorage.setItem("token", this.state.valid);
localStorage.setItem("userId", this.state.userId);
}
if (this.state.valid) return <Redirect to="/"></Redirect>;
return (
<div className='signup'>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="/">Stud-Shop</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ml-auto">
<li className="nav-item">
<i className="fas fa-home"></i>
</li>
<li className="nav-item">
Login
</li>
</ul>
</div>
</nav>
<img src={img} className='mobSignup'/>
<div className="row">
<div className="col-lg-3 bg-white rounded ">
<div className='card'>
<form>
<div className="form-group">
<h3>Sign-Up</h3>
<label htmlFor="exampleInputEmail1"><i class=" fa-lg fas fa-envelope"></i></label>
<input
type="email"
name="email"
className="form-control"
aria-describedby="emailHelp"
placeholder="Email-Address"
value={this.state.email}
onChange={this.handleChange}
></input>
<small className="form-text text-muted">
we'll never share your email with anyone!
</small>
<label><i class=" fa-lg fas fa-key"></i></label>
<input
value={this.state.password}
name="password"
type="password"
placeholder="Password (Min Length-6)"
className="form-control"
aria-describedby="emailHelp"
onChange={this.handleChange}
></input>
<label><i class=" fa-lg fas fa-user"></i></label>
<input
type="text"
name="name"
className="form-control"
placeholder="Name"
aria-describedby="emailHelp"
onChange={this.handleChange}
value={this.state.name}
></input>
<label><i class=" fa-lg fas fa-phone"></i>.</label>
<input
value={this.state.phone}
name="phone"
type="Number"
placeholder="Ph No. (Ex-98765XXXXX)"
className="form-control"
aria-describedby="emailHelp"
onChange={this.handleChange}
></input>
<label><i class=" fa-lg fas fa-home"></i></label>
<input
value={this.state.address}
type="text"
name="address"
className="form-control"
placeholder="Address"
aria-describedby="emailHelp"
onChange={this.handleChange}
></input>
<label><i class=" fa-lg fas fa-map-marked"></i></label>
<input
value={this.state.location}
type="text"
name="location"
className="form-control"
placeholder="Location (City)"
aria-describedby="emailHelp"
onChange={this.handleChange}
></input>
</div>
<button
type="submit"
onClick={this.signup}
className="btn btn-primary"
>
Sign-Up <i className=" fas fa-check"></i>
</button>
</form>
</div>
</div>
<div className='col-lg-8'>
<img src={img} className='signupImg'/>
</div>
</div>
</div>
);
}
}
export default Signup;
//model.js
const mongoose = require('mongoose');
const UserSchema = mongoose.Schema({
name: {
type: String,
required: true,
},
address: {
type: String,
required: true,
},
location: {
type: String,
required: true,
},
phone: {
type: Number,
required: true,
},
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
date: {
type: Date,
default: Date.now,
},},
{
collection:"Users"}
);
const model = mongoose.model('UserSchema', UserSchema)
module.exports = model
database connection is established. I tried to get the code from outside, but when I tried it with my code, it didn't work. What should I do? Can you help me?

System validation failed - Node / Express / Mongoose

When I submit my form I get the following error: Error [ValidationError]: System validation failed: lastName: Path lastName is required., firstName: Path firstName is required.
I'm not sure what's causing this, when I console.log(formData) I get the data I submitted into the form.
App.js
const express = require('express')
const app = express();
const mongoose = require('mongoose');
const dotenv = require ('dotenv/config');
const System = require('./models/System');
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.get('/', (req,res) => {
res.render('index.ejs');
});
app.post('/post-feedback', (req, res) => {
const formData = {
firstame: req.body.firstName,
lastname: req.body.lastName,
assetTag: req.body.assetTag
}
const system = new System(formData);
system.save()
.then(result => {
console.log(result);
})
.catch(err => {
console.log(err);
});
});
Model:
const mongoose = require('mongoose');
var SystemSchema = new mongoose.Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
assetTag: {
type: Number,
required: true
}
});
module.exports = mongoose.model('System', SystemSchema);
Form:
<form action="/post-feedback" method="POST">
<div class="form-group">
<label for="firstName">First Name: </label>
<input type="text" class="form-control" id="firstName" name="firstName">
</div>
<div class="form-group">
<label for="lastName">Last Name: </label>
<input type="text" class="form-control" id="lastName" name="lastName">
</div>
<div class="form-group">
<label for="assetNum">Asset Tag: </label>
<input type="text" class="form-control" id="assetTag" name="assetTag">
</div>
<button type="submit" name="submit" class="btn btn-primary">Submit</button>
</form>
The only one reason why you got some error it's because you're typo on your formData. It must be firstName and lastName, make sure it same with your Schema field and then Make Sure your assetTag is a number, because your Schema type is number.
You can try with this code below:
app.post('/post-feedback', (req, res) => {
const formData = {
// you're typo here: firstame
firstName: req.body.firstName,
// you're typo here: lastname
lastName: req.body.lastName,
// must be number
assetTag: parseInt(req.body.assetTag);
}
const system = new System(formData);
system.save()
.then(result => {
console.log(result);
})
.catch(err => {
console.log(err);
});
});
I hope it can help you.
app.post('/post-feedback', (req, res) => {
const system = new System(req.body);
system.save()
.then(result => {
console.log(result);
})
.catch(err => {
console.log(err);
});
});
i think above code should be work.

I have a schema in mongoose and i and rendering data from a schema to select the value. But now i also want the id of the selected data

Basically i have 2 sections. First is category and second is essay. The categories are added in mongoose schema and then the categories are being rendered to add essay in a specific category section. Now when i choose a specific category i also want the id of that category to store in essay schema but cant do so. Any help is appreciated
I have tried mongoose populate and schema.types.object method but aint
working for me.
// Loading essay model
require("../models/essay");
const essay = mongoose.model("essay");
// Loading category model
require("../models/category");
const category = mongoose.model("category");
// Essay processing form
router.get("/addessay", ensureAuthenticated, (req, res) => {
res.header(
"Cache-Control",
"no-cache, private, no-store, must-revalidate,max-stale=0, post-check=0,
pre-check=0"
);
category.find({}).then(category => {
res.render("addessay", {
category: category
});
});
});
// Post route to store essay in db
router.post("/essay/add", ensureAuthenticated, (req, res) => {
res.header(
"Cache-Control",
"no-cache, private, no-store, must-revalidate,max-stale=0, post-check=0, pre-check=0"
);
const newEssay = {
cat: req.body.category,
catg: req.body.categoryg,
body: req.body.body,
bodygreece: req.body.bodyg
};
new essay(newEssay).save().then(essay => {
req.flash("success_msg", "Essay Succesfully added");
res.redirect("/");
});
});
//Category Schema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// creating the schema
const categorySchema = new Schema({
category: {
type: String,
required: true
},
categorygreece: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
mongoose.model("category", categorySchema);
//Essay Schema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// creating the schema
const EssaySchema = new Schema({
cat: {
type: String,
required: true
},
catg: {
type: String,
required: true
},
body: {
type: String,
required: true
},
bodygreece: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
mongoose.model("essay", EssaySchema);
//Handlebar template (Essay adding form)
<main class="page-content my-5">
<div class="row">
<div class="col-md-6 offset-3">
<h3 class="my-5">Add Your your Essays .!</h3>
</div>
</div>
<div class="row">
<div class="col">
<form action="/essay/add" method="POST">
<div class="form-group">
<select class="categorys form-control mt-4" name="category">
{{#each category}}
<option value="{{id}}">{{category}}
</option>
{{/each}}
</select>
</div>
<div class="form-group">
<select class="categorys form-control mt-4" name="categoryg">
{{#each category}}
<option value="{{id}}">{{categorygreece}}
</option>
{{/each}}
</select>
</div>
<div class="form-group">
<h5 class="mb-3">Tell us your Essay in English!</h5>
<script src="https://cdn.ckeditor.com/4.11.4/standard/ckeditor.js"></script>
<textarea name="body" id="body-text" cols="30" rows="5" class="form-control"
placeholder="English Essay"></textarea>
<script>
CKEDITOR.replace('body');
</script>
</div>
<div class="form-group">
<h5 class="mb-3">Tell us your Essay in Greece!</h5>
<script src="https://cdn.ckeditor.com/4.11.4/standard/ckeditor.js"></script>
<textarea name="bodyg" id="body-text-2" cols="30" rows="5" class="form-control"
placeholder="Greece Essay"></textarea>
<script>
CKEDITOR.replace('bodyg');
</script>
</div>
<div class="form-group">
<input type="submit" value="SUBMIT" class="form-control btn btn-outline-dark btn-sm">
</div>
</form>
</div>
</div>
</main>
So when from options i choose a category i also want the categorys id and have to store that in essay schema.

Resources