I'm trying to consume but I've been receiving an error:
{error: {…}}
error
:
{clientVersion: '4.9.0'} but my api is working. I can't consume it on front-end
I put many console logs when I submit and the result is
{firstName: 'Matheus', lastName: 'Coppi', role: 'enginner', age: '23', email: 'matheus#gmail', …}
Response {type: 'cors', url: 'http://localhost:8080/register', redirected: false, status: 200, ok: true, …}
{error: {…}}
error: {clientVersion: '4.9.0'}
The error is my catch from my api
async createUser(req, res) {
try {
const {
firstName,
lastName,
role,
age,
email,
password
} = req.body
const salt = await bcrypt.genSalt();
console.log(salt)
const hash = await bcrypt.hash(password, salt)
console.log(hash)
const verifyemail = await prisma.UserInfo.findUnique({
where: {
email
}
})
if (verifyemail) {
return res.send({
"error": "true"
})
}
const user = await prisma.UserInfo.create({
data: {
firstName: firstName,
lastName: lastName,
role: role,
age: age,
email: email,
password: hash
}
});
return res.send(user)
} catch (error) {
return res.json({ error }) // The error client version is from here
}
}
Here is my react front-end
import { useState } from 'react';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
const Register = () => {
const [firstName, setFirstName] = useState('')
const [lastName, setlastName] = useState('')
const [role, setRole] = useState('')
const [age, setAge] = useState('')
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const handleSubmit = (e) => {
e.preventDefault()
const info = {firstName, lastName, role, age, email, password}
console.log(info)
fetch("http://localhost:8080/register", {
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify(info)
}).then(async response => {
console.log(response) //until here it works
try {
const data = await response.json()
console.log(data)
} catch(error) {
console.log('Error happened here!')
console.error(error)
}
})
}
return (
<div className='all1'>
<div className="container d-flex justify-content-center">
<Form onSubmit={handleSubmit}>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>First Name</Form.Label>
<Form.Control type="text" placeholder="First Name" value={firstName} onChange={(e) => setFirstName(e.target.value)}/>
<Form.Label>Last Name</Form.Label>
<Form.Control type="text" placeholder="Last Name" value={lastName} onChange={(e) => setlastName(e.target.value)} />
<Form.Label>Role</Form.Label>
<Form.Control type="text" placeholder="role" value={role} onChange={(e) => setRole(e.target.value)}/>
<Form.Label>Age</Form.Label>
<Form.Control type="number" placeholder="age" value={age} onChange={(e) => setAge(e.target.value)}/>
<Form.Label>Email address</Form.Label>
<Form.Control type="email" placeholder="Enter email" value={email} onChange={(e) => setEmail(e.target.value)}/>
<Form.Text className="text-muted">
We'll never share your email with anyone else.
</Form.Text>
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)}/>
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</div>
<div>{email}</div>
<div>{password}</div>
</div>
);
}
export default Register;
Related
I want to use my own API to check the information about email and password, but I don't know how to do that. Anything information that I put show up "Login" but I need to just show up "Login" if the information was the same that I registered in my database.
import { useState } from 'react';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
import { Link } from "react-router-dom"
const Login = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const handleSubmit = (e) => {
e.preventDefault()
const info = {email, password}
fetch('http://localhost:3333/login/', {
mode: 'no-cors',
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify(info)
}).then((response) => {
console.log(response)
console.log("login")
}).catch(() => {
console.log("NO")
})
}
return (
<div className="all ">
<div className='button d-flex justify-content-center '>
<Link to="/" className="text-center btn btn-secondary btn-lg m-4">Login</Link>
<Link to="/register" className="text-center btn btn-secondary btn-lg m-4">Register</Link>
</div>
<p className='text-center'>Sign With:</p>
<div className="container d-flex justify-content-center">
<Form onSubmit={handleSubmit}>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control type="email" value = {email} onChange={(e) => setEmail (e.target.value)} placeholder="Enter email" required/>
<Form.Text className="text-muted">
We'll never share your email with anyone else.
</Form.Text>
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" value = {password} onChange={e => setPassword(e.target.value)} placeholder="Password" />
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicCheckbox">
<Form.Check type="checkbox" label="Check me out" />
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</div>
</div>
);
}
export default Login;
My API is shown below and it's working fine and the login function is verifying well
const {
PrismaClient
} = require("#prisma/client");
const prisma = new PrismaClient();
const bcrypt = require('bcrypt');
module.exports = {
async createUser(req, res) {
try {
const {
firstName,
lastName,
email,
password,
age,
role
} = req.body
const salt = await bcrypt.genSalt();
console.log(salt)
const hash = await bcrypt.hash(password, salt)
console.log(hash)
const verifyemail = await prisma.UserInfo.findUnique({
where: {
email
}
})
if (verifyemail) {
return res.json({
error: "there is a email with the same name, please change."
})
}
const user = await prisma.UserInfo.create({
data: {
firstName: firstName,
lastName: lastName,
email: email,
password: hash,
age: age,
role: role
}
});
return res.json(user)
} catch (error) {
return res.json({
error
})
}
},
async login(req, res) {
try {
const {email, password} = req.body
const user = await prisma.UserInfo.findUnique({
where: {
email : req.body.email
}
})
if(user) {
const match = await bcrypt.compare(password, user.password)
if(match) {
return res.send("login")
}
else {
return res.send("There is something wrong with your password")
}
}
} catch (error) {
return res.json({
error
})
}
}
}
What I have understood from your question is that, no matter what username and password you are entering you are always ending up in the .then block, while if the username/password is wrong it should go to the catch block.
If I have understood that correctly, I would suggest updating your node code to handle this scenario. Fetch will only go in catch if there is a network error or CORS error, check this
With this, I would suggest you can add an else block in your Node code and add
return res.status(401).send("Icorrect password");
after this, in front end code, you can add
.then(response => /* check response status code and throw 'Incorrect' if 401 */ )
I am building a nodejs, reactjs app and i am having issues for making requests from my reactjs part of the app to my API. I am using concurrently, so i made a proxy:
"proxy":"http://localhost:5000/"
Port 5000 is where my API is running and Port 3000 is where my ReactJs runs.
When i try to register a new user i get the following error
Cannot POST api/users
And my console shows what url is trying to request http://localhost:3000/api/users
But instead it should be http://localhost:5000/api/users
This is my Register.js:
import React, { Fragment, useState } from 'react'
import axios, { Axios } from 'axios';
const Register = () => {
const [formData, setFormData] = useState({
name:'',
email: '',
password: '',
password2: ''
});
const { name, email, password, password2 } = formData;
const onChange = e => setFormData({
...formData, [e.target.name]:e.target.value
});
const onSubmit = async e => {
e.preventDefault();
if(password !== password2){
console.log('Passwords do not match')
} else {
const newUser = {
name,
email,
password
}
try {
const config = {
headers:{
'Content-type': 'application/json'
}
}
const body = JSON.stringify(newUser)
const res = await axios.post('api/users', body, config);
console.log(res.data);
} catch (error) {
console.error(error.response.data)
}
}
}
return (
<Fragment>
<section className='container'>
<h1 className="large text-primary">Sign Up</h1>
<p className="lead"><i className="fas fa-user"></i> Create Your Account</p>
<form className="form" action="create-profile.html" onSubmit={e => onSubmit(e)}>
<div className="form-group">
<input type="text"
placeholder="Name"
name="name"
value={name}
onChange={e => onChange(e)}
required />
</div>
<div className="form-group">
<input type="email"
placeholder="Email Address"
name="email" value={email}
onChange={e => onChange(e)}
required/>
<small className="form-text"
>This site uses Gravatar so if you want a profile image, use a
Gravatar email</small
>
</div>
<div className="form-group">
<input
type="password"
placeholder="Password"
name="password"
minLength="6"
value={password}
onChange={e => onChange(e)}
required
/>
</div>
<div className="form-group">
<input
type="password"
placeholder="Confirm Password"
name="password2"
minLength="6"
value={password2}
onChange={e => onChange(e)}
required
/>
</div>
<input type="submit" className="btn btn-primary" value="Register" />
</form>
<p className="my-1">
Already have an account? Sign In
</p>
</section>
</Fragment>
)
}
export default Register
And this is my users.js
//#route POST api/users
//#desc Register user
//#access public
router.post('/', [
check('name', 'Name is required')
.not()
.isEmpty(),
check('email', 'Plese include a valid email').isEmail(),
check('password', 'Please enter a password with 6 or more characters').isLength({min:6})
],
async (req, res)=> {
const errors = validationResult(req);
if(!errors.isEmpty()){
return res.status(400).json({ errors:errors.array()}); //400 is for bad requests
}
const { name, email, password } = req.body;
try{
//See if user exists
let user = await User.findOne({ email });
if(user){
return res.status(400).json({ errors: [{ msg:'User already exists' }] });
}
//Get users gravatar
const avatar = gravatar.url(email,{
s:'200',
r:'pg',
d:'mm'
})
user = new User({
name,
email,
avatar,
password
});
//Encrypt password
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
//Return jsonwebtoken -> this for users to be logged in right after registration
const payload = {
user:{
id: user.id
}
}
jwt.sign(
payload,
config.get('jwtSecret'),
{expiresIn: 360000}, //change to 3600 for production
(err, token)=>{
if(err) throw err;
res.json({ token });
}
)
}catch(err){
console.error('err.message');
res.status(500).send('Server Error');
}
});
module.exports = router;
What am i doing wrong? What is the solution to this error?
I am devloping a webapp with nodejs and reactjs with redux. I am trying to make a request to register a new user but i am getting a bad request.
This is the error i am getting:
POST http://localhost:5000/api/users 400 bad request
This is my users route:
const express = require('express');
const config = require('config');
const router = express.Router();
const gravatar = require('gravatar');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const { check , validationResult } = require('express-validator/');
const User = require('../../models/User');
//#route POST api/users
//#desc Register user
//#access public
router.post('/', [
check('name', 'Name is required')
.not()
.isEmpty(),
check('email', 'Plese include a valid email').isEmail(),
check('password', 'Please enter a password with 6 or more characters').isLength({min:6})
],
async (req, res)=> {
const errors = validationResult(req);
if(!errors.isEmpty()){
return res.status(400).json({ errors:errors.array()}); //400 is for bad requests
}
const { name, email, password } = req.body;
try{
//See if user exists
let user = await User.findOne({ email });
if(user){
return res.status(400).json({ errors: [{ msg:'User already exists' }] });
}
//Get users gravatar
const avatar = gravatar.url(email,{
s:'200',
r:'pg',
d:'mm'
})
user = new User({
name,
email,
avatar,
password
});
//Encrypt password
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
//Return jsonwebtoken -> this for users to be logged in right after registration
const payload = {
user:{
id: user.id
}
}
jwt.sign(
payload,
config.get('jwtSecret'),
{expiresIn: 360000}, //change to 3600 for production
(err, token)=>{
if(err) throw err;
res.json({ token });
}
)
}catch(err){
console.error('err.message');
res.status(500).send('Server Error');
}
});
module.exports = router;
The route is not the problem i think because if i register manually a user via postman it works.
This is my register.js component:
import React, { useState } from 'react';
import { connect } from 'react-redux';
import { Link, Navigate } from 'react-router-dom';
import { setAlert } from '../../actions/alert';
import { register } from '../../actions/auth';
import PropTypes from 'prop-types';
const Register = ({ setAlert, register }) => {
const [formData, setFormData] = useState({
name: '',
email: '',
password: '',
password2: ''
});
const { name, email, password, password2 } = formData;
const onChange = (e) =>
setFormData({ ...formData, [e.target.name]: e.target.value });
const onSubmit = async (e) => {
e.preventDefault();
if (password !== password2) {
setAlert('Passwords do not match', 'danger');
} else {
register({ name, email, password });
console.log('SUCCESS')
}
};
return (
<section className="container">
<h1 className="large text-primary">Sign Up</h1>
<p className="lead">
<i className="fas fa-user" /> Create Your Account
</p>
<form className="form" onSubmit={onSubmit}>
<div className="form-group">
<input
type="text"
placeholder="Name"
name="name"
value={name}
onChange={onChange}
/>
</div>
<div className="form-group">
<input
type="email"
placeholder="Email Address"
name="email"
value={email}
onChange={onChange}
/>
<small className="form-text">
This site uses Gravatar so if you want a profile image, use a
Gravatar email
</small>
</div>
<div className="form-group">
<input
type="password"
placeholder="Password"
name="password"
value={password}
onChange={onChange}
/>
</div>
<div className="form-group">
<input
type="password"
placeholder="Confirm Password"
name="password2"
value={password2}
onChange={onChange}
/>
</div>
<input type="submit" className="btn btn-primary" value="Register" />
</form>
<p className="my-1">
Already have an account? <Link to="/login">Sign In</Link>
</p>
</section>
);
};
Register.propTypes = {
setAlert: PropTypes.func.isRequired,
register: PropTypes.func.isRequired
};
export default connect( null, { setAlert , register })(Register);
and this is one of my actions auth.js where i request my api
import axios from "axios";
import { setAlert } from './alert'
import {
REGISTER_SUCCESS,
REGISTER_FAIL
} from './types'
//Register user
export const register = ( { name, email, password } ) => async dispatch => {
const config = {
headers: {
'Content-type': 'application/json'
}
}
const body = JSON.stringify({ name , email, password });
try {
const res = await axios.post('http://localhost:5000/api/users', body, config);
dispatch({
type: REGISTER_SUCCESS,
payload: res.data
});
} catch (error) {
const errors = error.response.data.errors;
if(errors){
errors.forEach(error => dispatch(setAlert(error.msg, 'danger')));
}
dispatch({
type:REGISTER_FAIL
});
}
}
I am pretty sure this might be an axios error on how i am trying to perform a request or a redux mistake.
My app works fine, if i don´t enter or enter invalid data to my registration form all my validation alerts show up. The issue is when i submit the form and try to send the data to register the new user.
I am trying to store data from an option, but I'm not sure where I went wrong in the schema or the react code. Is there another I could perhaps do it?
When I run it I get this error.
POST http://localhost:8080/api/user 500 (Internal Server Error)
Here is my model
model.js
const mongoose = require('mongoose');
const jwt = require('jsonwebtoken');
const joi = require('joi');
const { optional } = require('joi');
const userSchema = new mongoose.Schema({
firstName:{type: String, required: true},
lastName:{type: String, required: true},
email:{type: String, required: true},
password:{type: String, required: true},
status:{type: String, enum: ['active', 'inactive'],required : true },
});
userSchema.methods.generateAuthToken = function(){
const token = jwt.sign({_id:this._id}, process.env.JWTPRIVATEKEY)
return token
}
const User = mongoose.model("user", userSchema);
const validate = (data) => {
const schema = joi.object({
firstName:joi.string().required().label("First Name"),
lastName:joi.string().required().label("Last Name"),
email: joi.string().email().required().label("Email"),
password: joi.string().required().label("password"),
status:joi.string().enum['active', 'inactive'].required().label(" ")
});
return schema.validate(data)
}
module.exports = {User, validate}
When I run it I get "error creating user"
routes user.js
const router =require("express").Router();
const {User, validate} = require('../models/user')
const bcrypt = require("bcrypt");
router.post("/", async(req, res) => {
try{
const {error} = validate(req.body)
if(error)
return res.status(400).send({message: error.details[0].message})
const user = await User.findOne({ email:req.body.email})
if (user)
return res.status(409).send({message: "duplicate email"})
const salt = await bcrypt.genSalt(Number(process.env.SALT))
const hashPassword = await bcrypt.hash(req.body.password, salt);
await new User({...req.body, password: hashPassword}).save();
res.status(201).send({message: "User created succesfully"})
}catch(error){
console.log(error.details)
res.status(500).send({message: "Error creating user"})
}
})
module.exports = router;
here are my react.js files, I believe my error should lie here but I maybe be mistaken.
index.jsx
import { useState, useEffect } from "react";
import axios from "axios";
import { Link, useNavigate } from "react-router-dom";
import styles from "./styles.module.css";
const Signup = () => {
const [data, setData] = useState({
firstName: "",
lastName: "",
email: "",
password: "",
status: "",
});
const [error, setError] = useState("");
const navigate = useNavigate();
const handleChange = ({ currentTarget: input }) => {
setData({ ...data, [input.name]: input.value });
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
const url = "http://localhost:8080/api/user";
const { data: res } = await axios.post(url, data);
navigate("/login");
console.log(res.message);
} catch (error) {
if (
error.response &&
error.response.status >= 400 &&
error.response.status <= 500
) {
setError(error.response.data.message);
}
}
};
return (
<div className={styles.signup_container}>
<div className={styles.signup_form_container}>
<div className={styles.left}>
<h1>Welcome Back</h1>
<Link to="/login">
<button type="button" className={styles.white_btn}>
Sign in
</button>
</Link>
</div>
<div className={styles.right}>
<form className={styles.form_container} onSubmit={handleSubmit}>
<h1>Create Account</h1>
<input
type="text"
placeholder="First Name"
name="firstName"
onChange={handleChange}
value={data.firstName}
required
className={styles.input}
/>
<input
type="text"
placeholder="Last Name"
name="lastName"
onChange={handleChange}
value={data.lastName}
required
className={styles.input}
/>
<input
type="email"
placeholder="Email"
name="email"
onChange={handleChange}
value={data.email}
required
className={styles.input}
/>
<input
type="password"
placeholder="Password"
name="password"
onChange={handleChange}
value={data.password}
required
className={styles.input}
/>
<select name ="status">
<option value="1">active</option>
<option value="2">inactive</option>
</select>
{error && <div className={styles.error_msg}>{error}</div>}
<button type="submit" className={styles.green_btn}>
Sign Up
</button>
</form>
</div>
</div>
</div>
);
};
export default Signup;
I have created a react client and sending my register form request to node server but I am getting the following error in my console while clicking the register button.
"POST http://localhost:3000/users/register 404 (Not Found)"
Please suggest a solution to it?
../routes/User.js
const users = express.Router()
const cors = require('cors')
const jwt = require("jsonwebtoken")
const bcrypt = require('bcrypt')
const User = require("../models/User")
users.use(cors())
process.env.SECRET_KEY = 'secret'
users.post('/register', (req, res) => {
const today = new Date()
const userData = {
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
password: req.body.password,
created: today
}
User.findOne({
where: {
email: req.body.email
}
})
.then(user => {
if(!user){
bcrypt.hash(req.body.password, 10, (err, hash) => {
userData.password = hash
User.create(userData)
.then(user => {
res.json({status: user.email + ' registered'})
})
.catch(err => {
res.send('error: ' + err)
})
})
} else {
res.json({error: "User already exists"})
}
})
.catch(err => {
res.send('error: ' + err)
})
})
users.post('/login', (req, res) => {
User.findOne({
where: {
email: req.body.email
}
})
.then(user => {
if(user) {
if(bcrypt.compareSync(req.body.password, user.password)) {
let token = jwt.sign(user.dataValues, process.env.SECRET_KEY, {
expiresin: 1440
})
res.send(token)
}
} else {
res.status(400).json({error: 'User does not exist'})
}
})
.catch(err => {
res.status(400).json({ error: err})
})
})
module.exports = users
../client/App.js
import './App.css';
import {BrowserRouter as Router, Route} from 'react-router-dom'
import Navbar from './components/Navbar'
import Landing from './components/Landing'
import Login from './components/Login'
import Register from './components/Register'
import Profile from './components/Profile'
function App() {
return (
<Router>
<div className="App">
<Navbar />
<Route exact path="/" component={Landing} />
<div className="container">
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profile" component={Profile} />
</div>
</div>
</Router>
);
}
export default App;
../client/src/Register.js
import { register } from './UserFunctions'
class Register extends Component {
constructor() {
super()
this.state = {
first_name: '',
last_name: '',
email: '',
password: ''
}
this.onChange = this.onChange.bind(this)
this.onSubmit = this.onSubmit.bind(this)
}
onChange(e){
this.setState({[e.target.name]: [e.target.value]})
}
onSubmit(e){
e.preventDefault()
const user = {
first_name: this.state.first_name,
last_name: this.state.last_name,
email: this.state.email,
password: this.state.password
}
register(user).then(res=> {
this.props.history.push(`/login`)
})
}
render(){
return(
<div className="container">
<div className="row">
<div className="col-md-6 mt-5 mx-auto">
<form noValidate onSubmit={this.onSubmit}>
<h1 className="h3 mb-3 font-weight-normal">Please sign in</h1>
<div className="form-group">
<label htmlFor="first_name">First Name</label>
<input type="text"
className="form-control"
name="first_name"
placeholder="Enter First Name"
value={this.state.first_name}
onChange={this.onChange}/>
</div>
<div className="form-group">
<label htmlFor="last_name">Last Name</label>
<input type="text"
className="form-control"
name="last_name"
placeholder="Enter Last Name"
value={this.state.last_name}
onChange={this.onChange}/>
</div>
<div className="form-group">
<label htmlFor="email">Email Address</label>
<input type="email"
className="form-control"
name="email"
placeholder="Enter Email"
value={this.state.email}
onChange={this.onChange}/>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input type="password"
className="form-control"
name="password"
placeholder="Enter Password"
value={this.state.password}
onChange={this.onChange}/>
</div>
<button type="submit"
className="btn btn-lg btn-primary btn-block">
Register
</button>
</form>
</div>
</div>
</div>
)
}
}
export default Register
../server.js
var cors = require ('cors')
var bodyParser = require("body-parser")
var app = express()
var port = process.env.PORT || 5000
app.use(bodyParser.json())
app.use(cors())
app.use(bodyParser.urlencoded({extended: false}))
var Users = require('./routes/users')
app.use('/users', Users)
app.listen(port, () => {
console.log("Server is running at port: " + port)
})
./client/src/UserFunctions.js
export const register = newUser => {
return axios
.post('users/register', {
first_name: newUser.firstname,
last_name: newUser.last_name,
email: newUser.email,
password: newUser.password
})
.then(res => {
console.log("Registered");
})
}
export const login = user => {
return axios
.post('users/login', {
email: user.email,
password: user.password
})
.then(res=>{
localStorage.setItem('usertoken', res.data)
return res.data
})
.catch(err => {
console.log(err)
})
}
Looking at this, it seems the problem may be with your client code.
You're trying to access http://localhost:3000/users/register, which is an inexistent route on your client but it exists on the server as http://localhost:5000/users/register. (that's assuming that your server is running on port 5000).
If your server is running on port 5000, you can try this in your register function...
return axios.post('http://localhost:5000/users/register') // add the rest of your code
Unless you have a proxy for your server set up in the client, you'll keep getting that error.