Checkbox doesn't change after clicking React - node.js

I need to update options so that later useCallback will process it, but when I click on the checkbox, nothing changes.
But if you comment out setOptions, then the checkbox changes
const [options, setOptions] = useState({
s22: {value: 'TRUE', s: 22},
s23: {value: 'TRUE', s: 23},
s24: {value: 'TRUE', s: 24}
})
const changeFilter = event => {
setOptions({ ...options, [event.target.name]: {
value: event.target.checked.toString().toUpperCase(),
s: event.target.value
}
})
}
<div id="filter">
<p>
<label>
<input name="s22" type="checkbox" value="22" onChange={changeFilter} />
<span>УК</span>
</label>
</p>
<p>
<label>
<input name="s23" type="checkbox" value="23" onChange={changeFilter} />
<span>ФК</span>
</label>
</p>
<p>
<label>
<input name="s24" type="checkbox" value="24" onChange={changeFilter} />
<span>ФТ</span>
</label>
</p>
</div>
Found similar questions but there was a problem with preventDefault
Full code
import React, {useCallback, useContext, useEffect, useState} from 'react'
import {useHttp} from '../hooks/http.hook'
import {AuthContext} from '../context/AuthContext'
import {Loader} from '../components/Loader'
export const TreePage = () => {
const [tree, setTree] = useState([])
const [options, setOptions] = useState({
s22: {value: 'TRUE', s: 22},
s23: {value: 'TRUE', s: 23},
s24: {value: 'TRUE', s: 24}
})
const {loading, request} = useHttp()
const {token} = useContext(AuthContext)
const fetchTree = useCallback(async () => {
try {
const fetched = await request('/api/tree', 'GET', options, {
Authorization: `Bearer ${token}`
})
setTree(fetched)
} catch (e) {}
}, [token, request, options])
useEffect(() => {
fetchTree()
}, [fetchTree])
useEffect(() => {
var zoom = 1;
var zoomStep = 0.1;
document.getElementById("zoomIn").addEventListener("click",function(){
zoom += zoomStep; document.getElementById("zoomtext").style.transform = "scale("+zoom+")";
});
document.getElementById("zoomOut").addEventListener("click",function(){
if(zoom > zoomStep){
zoom -= zoomStep;
document.getElementById("zoomtext").style.transform = "scale("+zoom+")";
}
});
})
const changeFilter = event => {
setOptions({ ...options, [event.target.name]: {
value: event.target.checked.toString().toUpperCase(),
s: event.target.value
}
})
}
if (loading) {
return <Loader/>
}
return (
<>
{!loading &&
<div className="row">
<div className="col s6 offset-s3">
<div id="filter">
<p>
<label>
<input name="s22" type="checkbox" value="22" onChange={changeFilter} />
<span>УК</span>
</label>
</p>
<p>
<label>
<input name="s23" type="checkbox" value="23" onChange={changeFilter} />
<span>ФК</span>
</label>
</p>
<p>
<label>
<input name="s24" type="checkbox" value="24" onChange={changeFilter} />
<span>ФТ</span>
</label>
</p>
</div>
<div dangerouslySetInnerHTML={{__html: tree}}></div>
</div>
</div>
}
</>
)
}

Related

cannot display fields in the web page reactjs

i was trying to make a restaurant review application using mern stack but in the frontend , i keep getting a problem in the react.
The pages load perfectly in the main page where the code as follows
import React, { useState, useEffect } from "react";
import RestaurantDataService from "../services/restaurant";
import { Link } from "react-router-dom";
const RestaurantsList = props => {
const [restaurants, setRestaurants] = useState([]);
const [searchName, setSearchName ] = useState("");
const [searchZip, setSearchZip ] = useState("");
const [searchCuisine, setSearchCuisine ] = useState("");
const [cuisines, setCuisines] = useState(["All Cuisines"]);
useEffect(() => {
retrieveRestaurants();
retrieveCuisines();
}, []);
const onChangeSearchName = e => {
const searchName = e.target.value;
setSearchName(searchName);
};
const onChangeSearchZip = e => {
const searchZip = e.target.value;
setSearchZip(searchZip);
};
const onChangeSearchCuisine = e => {
const searchCuisine = e.target.value;
setSearchCuisine(searchCuisine);
};
const retrieveRestaurants = () => {
RestaurantDataService.getAll()
.then(response => {
console.log(response.data);
setRestaurants(response.data.restaurants);
})
.catch(e => {
console.log(e);
});
};
const retrieveCuisines = () => {
RestaurantDataService.getCuisines()
.then(response => {
console.log(response.data);
setCuisines(["All Cuisines"].concat(response.data));
})
.catch(e => {
console.log(e);
});
};
const refreshList = () => {
retrieveRestaurants();
};
const find = (query, by) => {
RestaurantDataService.find(query, by)
.then(response => {
console.log(response.data);
setRestaurants(response.data.restaurants);
})
.catch(e => {
console.log(e);
});
};
const findByName = () => {
find(searchName, "name")
};
const findByZip = () => {
find(searchZip, "zipcode")
};
const findByCuisine = () => {
if (searchCuisine === "All Cuisines") {
refreshList();
} else {
find(searchCuisine, "cuisine")
}
};
return (
<div>
<div className="row pb-1">
<div className="input-group col-lg-4">
<input
type="text"
className="form-control"
placeholder="Search by name"
value={searchName}
onChange={onChangeSearchName}
/>
<div className="input-group-append">
<button
className="btn btn-outline-secondary"
type="button"
onClick={findByName}
>
Search
</button>
</div>
</div>
<div className="input-group col-lg-4">
<input
type="text"
className="form-control"
placeholder="Search by zip"
value={searchZip}
onChange={onChangeSearchZip}
/>
<div className="input-group-append">
<button
className="btn btn-outline-secondary"
type="button"
onClick={findByZip}
>
Search
</button>
</div>
</div>
<div className="input-group col-lg-4">
<select onChange={onChangeSearchCuisine}>
{cuisines.map(cuisine => {
return (
<option value={cuisine}> {cuisine.substr(0, 20)} </option>
)
})}
</select>
<div className="input-group-append">
<button
className="btn btn-outline-secondary"
type="button"
onClick={findByCuisine}
>
Search
</button>
</div>
</div>
</div>
<div className="row">
{restaurants.map((restaurant) => {
const address = `${restaurant.address.building} ${restaurant.address.street}, ${restaurant.address.zipcode}`;
return (
<div className="col-lg-4 pb-1">
<div className="card">
<div className="card-body">
<h5 className="card-title">{restaurant.name}</h5>
<p className="card-text">
<strong>Cuisine: </strong>{restaurant.cuisine}<br/>
<strong>Address: </strong>{address}
</p>
<div className="row">
<Link to={"/restaurants/"+restaurant._id} className="btn btn-primary col-lg-5 mx-1 mb-1">
View Reviews
</Link>
<a target="_blank" href={"https://www.google.com/maps/place/" + address} className="btn btn-primary col-lg-5 mx-1 mb-1">View Map</a>
</div>
</div>
</div>
</div>
);
})}
</div>
</div>
);
};
export default RestaurantsList;
but the problem arise when i click the view review button in the card shown in this page where the screen does not show anything and recieve anything kind of data. the code as follows:
import React, { useState, useEffect } from "react";
import RestaurantDataService from "../services/restaurant";
import { Link } from "react-router-dom";
const Restaurant = props => {
const initialRestaurantState = {
id: null,
name: "",
address: {},
cuisine: "",
reviews: []
};
const [restaurant, setRestaurant] = useState(initialRestaurantState);
const getRestaurant = id => {
RestaurantDataService.get(id)
.then(response => {
setRestaurant(response.data);
console.log(response.data);
})
.catch(e => {
console.log(e);
});
};
useEffect(() => {
getRestaurant(props.match.params.id);
}, [props.match.params.id]);
const deleteReview = (reviewId, index) => {
RestaurantDataService.deleteReview(reviewId, props.user.id)
.then(response => {
setRestaurant((prevState) => {
prevState.reviews.splice(index, 1)
return({
...prevState
})
})
})
.catch(e => {
console.log(e);
});
};
return (
<div>
{restaurant ? (
<div>
<h5>{restaurant.name}</h5>
<p>
<strong>Cuisine: </strong>{restaurant.cuisine}<br/>
<strong>Address: </strong>{restaurant.address.building} {restaurant.address.street}, {restaurant.address.zipcode}
</p>
<Link to={"/restaurants/" + props.match.params.id + "/review"} className="btn btn-primary">
Add Review
</Link>
<h4> Reviews </h4>
<div className="row">
{restaurant.reviews.length > 0 ? (
restaurant.reviews.map((review, index) => {
return (
<div className="col-lg-4 pb-1" key={index}>
<div className="card">
<div className="card-body">
<p className="card-text">
{review.text}<br/>
<strong>User: </strong>{review.name}<br/>
<strong>Date: </strong>{review.date}
</p>
{props.user && props.user.id === review.user_id &&
<div className="row">
<a onClick={() => deleteReview(review._id, index)} className="btn btn-primary col-lg-5 mx-1 mb-1">Delete</a>
<Link to={{
pathname: "/restaurants/" + props.match.params.id + "/review",
state: {
currentReview: review
}
}} className="btn btn-primary col-lg-5 mx-1 mb-1">Edit</Link>
</div>
}
</div>
</div>
</div>
);
})
) : (
<div className="col-sm-4">
<p>No reviews yet.</p>
</div>
)}
</div>
</div>
) : (
<div>
<br />
<p>No restaurant selected.</p>
</div>
)}
</div>
);
};
export default Restaurant;
please kindly answer the question if possible

having issues running my react app locally

I have added my backend to heroku and my frontend to netlify, however when I'm trying to run my app whether it is locally or via netlify I'm getting the below error message when logging in or/and registering:
Uncaught Error: Element type is invalid: expected a string (for
built-in components) or a class/function (for composite components)
but got: object. You likely forgot to export your component from the
file it's defined in, or you might have mixed up default and named
imports.
what am I missing?
see below my app.js and signin.js for the frontend:
here is my APP.JS
import React, {Component} from 'react';
// import Clarifai from 'clarifai';
import Navigation from './components/Navigation/Navigation';
import Logo from './components/Logo/Logo';
import ImageLinkForm from './components/ImageLinkForm/ImageLinkForm';
import FaceRecognition from './components/FaceRecognition/FaceRecognition';
import Rank from './components/Rank/Rank';
import Signin from './components/Signin/Signin';
import Register from './components/Register/Register';
import './App.css';
const intialState = {
input: '',
imageUrl: '',
box: {},
route: 'signin',
isSignedIn: false,
user: {
id: '',
name: '',
email: '',
entries: 0,
joined: ''
}
}
class App extends Component {
constructor() {
super();
this.state = intialState
}
loadUser = (data) => {
this.setState({user: {
id: data.id,
name: data.name,
email: data.email,
entries: data.entries,
joined: data.joined
}})
}
calculateFaceLocation =(data) => {
const clarifaiFace = data.outputs[0].data.regions[0].region_info.bounding_box;
const image = document.getElementById('inputimage');
const width = Number(image.width);
const height = Number(image.height);
return {
leftCol: clarifaiFace.left_col * width,
topRow: clarifaiFace.top_row * height,
rightCol: width - clarifaiFace.right_col * width,
bottomRow: height - clarifaiFace.bottom_row * height,
};
}
displayFaceBox = (box) => {
console.log(box)
this.setState({box: box});
}
onInputChange = (event) => {
this.setState({input: event.target.value})
}
onButtonSubmit = () => {
this.setState({imageUrl: this.state.input})
fetch('https://ancient-sea-46547.herokuapp.com/imageurl', {
method: 'post',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
input: this.state.input
})
})
.then(response => response.json())
.then( response => {
if (response) {
fetch('https://ancient-sea-46547.herokuapp.com/image', {
method: 'put',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
id: this.state.user.id
})
})
.then(response => response.json())
.then(count => {
this.setState(Object.assign(this.state.user, { entries: count}))
})
.catch(console.log)
}
this.displayFaceBox(this.calculateFaceLocation(response))
})
.catch(err => console.log(err));
}
onRouteChange = (route) => {
if (route === 'signout') {
this.setState(intialState)
} else if (route === 'home') {
this.setState({isSignedIn: true})
}
this.setState({route:route});
}
render() {
return (
<div className="App">
<Navigation isSignedIn={this.state.isSignedIn} onRouteChange={this.onRouteChange} />
{ this.state.route === 'home'
? <div>
<Logo />
<Rank
name={this.state.user.name}
entries={this.state.user.entries}/>
<ImageLinkForm
onInputChange={this.onInputChange}
onButtonSubmit={this.onButtonSubmit} />
<FaceRecognition box={this.state.box} imageUrl={this.state.imageUrl}/>
</div>
:(
this.state.route === 'signin'
?<Signin loadUser={this.loadUser} onRouteChange={this.onRouteChange} />
:<Register loadUser={this.loadUser} onRouteChange={this.onRouteChange} />
)
}
</div>
);
}
}
export default App;
SIGNIN.JS
import React from 'react';
class Signin extends React.Component {
constructor(props) {
super(props);
this.state = {
signInEmail: '',
signInPassword: ''
}
}
onEmailChange = (event) => {
this.setState({signInEmail: event.target.value})
}
onPasswordChange = (event) => {
this.setState({signInPassword: event.target.value})
}
onSubmitSignIn = () => {
fetch('https://ancient-sea-46547.herokuapp.com/signin', {
method: 'post',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
email: this.state.signInEmail,
password: this.state.signInPassword
})
})
.then(response => response.json())
.then(user => {
if (user.id) {
this.props.loadUser(user);
this.props.onRouteChange('home');
}
})
}
render() {
const { onRouteChange} = this.props;
return (
<article className="br3 ba b--black-10 mv4 w-100 w-50-m w-25-l mw6 shadow-5 center">
<main className="pa4 black-80">
<div className="measure">
<fieldset id="sign_up" className="ba b--transparent ph0 mh0">
<legend className="f1 fw6 ph0 mh0">Sign In</legend>
<div className="mt3">
<label className="db fw6 lh-copy f6" for="email-address">Email</label>
<input
className="pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100"
type="email"
name="email-address"
id="email-address"
onChange={this.onEmailChange}
/>
</div>
<div className="mv3">
<label className="db fw6 lh-copy f6" for="password">Password</label>
<input
className="b pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100"
type="password"
name="password"
id="password"
onChange={this.onPasswordChange}
/>
</div>
</fieldset>
<div className="">
<input
onClick={this.onSubmitSignIn}
className="b ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib"
type="submit"
value="Sign in" />
</div>
<div className="lh-copy mt3">
<p onClick={() => onRouteChange('register')} className="f6 link dim black db pointer">Register</p>
</div>
</div>
</main>
</article>
);
}
}
export default Signin;
here is my server.js
const express = require('express');
const bodyParser = require('body-parser');
const bcrypt = require('bcrypt-nodejs');
const cors = require('cors');
const knex = require('knex');
const register = require('./controllers/register');
const signin = require('./controllers/signin');
const profile = require('./controllers/profile');
const image = require('./controllers/image');
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '1';
const db = knex({
client: 'pg',
connection: {
connectionString : process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
}
}
});
const app = express();
app.use(bodyParser.json())
app.use(cors())
app.get('/', (req, res) => {res.send('it is working') })
app.post('/signin', (req, res) => {signin.handleSignin(req, res, db, bcrypt)})
app.post('/register', (req, res) => {register.handleRegister(req, res, db, bcrypt)})
app.get('/profile/:id', (req, res) => {profile.handleProfile(req, res, db)})
app.put('/image', (req, res) => {image.handleImage(req, res, db)})
app.post('/imageurl', (req, res) => {image.handleApiCall(req, res)})
app.listen(process.env.PORT || 3001, () => {
console.log(`app is running on port ${process.env.PORT}`)
})
register.js
import React from 'react';
class Register extends React.Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
name: ''
}
}
onNameChange = (event) => {
this.setState({name: event.target.value})
}
onEmailChange = (event) => {
this.setState({email: event.target.value})
}
onPasswordChange = (event) => {
this.setState({password: event.target.value})
}
onSubmitSignIn = () => {
fetch('https://ancient-sea-46547.herokuapp.com/register', {
method: 'post',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
email: this.state.email,
password: this.state.password,
name: this.state.name
})
})
.then(response => response.json())
.then(user => {
if (user.id) {
this.props.loadUser(user)
this.props.onRouteChange('home');
}
})
}
render() {
return (
<article className="br3 ba b--black-10 mv4 w-100 w-50-m w-25-l mw6 shadow-5 center">
<main className="pa4 black-80">
<div className="measure">
<fieldset id="sign_up" className="ba b--transparent ph0 mh0">
<legend className="f1 fw6 ph0 mh0">Register</legend>
<div className="mt3">
<label className="db fw6 lh-copy f6" for="name">Name</label>
<input
className="pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100"
type="text"
name="name"
id="name"
onChange={this.onNameChange}
/>
</div>
<div className="mt3">
<label className="db fw6 lh-copy f6" for="email-address">Email</label>
<input
className="pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100"
type="email"
name="email-address"
id="email-address"
onChange={this.onEmailChange}
/>
</div>
<div className="mv3">
<label className="db fw6 lh-copy f6" for="password">Password</label>
<input
className="b pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100"
type="password"
name="password"
id="password"
onChange={this.onPasswordChange}
/>
</div>
</fieldset>
<div className="">
<input
onClick={this.onSubmitSignIn}
className="b ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib"
type="submit"
value="Register" />
</div>
<div className="lh-copy mt3">
</div>
</div>
</main>
</article>

Warning: Each child in a list should have a unique "key" prop and does not save in my json-server

I keep getting error "Warning: Each child in a list should have a unique "key" prop" on console log. I think there is something wrong in the
axios.delete('http://localhost:3000/contacts/${id}
' or
axios.put('http://localhost:3000/contacts/${isUpdate.id}'
It works, but does not configure in the json-server that I made. So the changes does not happen in the json-server.
The "save" button works, and added new data into my json-server. But, when I tried to edit, or delete, it does not save the changed in json-server.
My code:
import "./App.css";
import List from "./List";
import { useState,useEffect } from "react";
import {uid} from "uid";
import axios from "axios";
function App() {
const [contacts, setContacts] = useState([]);
function handleChange(e) {
let data = { ...formData };
data[e.target.name] = e.target.value;
setFormData(data);
}
const [isUpdate, setIsUpdate] = useState({ id: null, status: false});
const [formData, setFormData] = useState({
name: "",
telp: "",
});
useEffect(() => {
axios.get("http://localhost:3000/contacts").then((res) => {
console.log(res.data);
setContacts(res?.data ?? []);
});
}, []);
function handleSubmit(e){
e.preventDefault();
alert("Oke Bos!");
let data = [...contacts];
if(formData.name === "") {
return false;
}
if(formData.telp === "") {
return false;
}
if ( isUpdate.status){
data.forEach((contact) => {
if (contact.id === isUpdate.id) {
contact.name = formData.name;
contact.telp = formData.telp;
}
});
axios.put('http://localhost:3000/contacts/${isUpdate.id}', {
name: formData.name,
telp: formData.telp,
})
.then((res) => {
alert("Berhasil edit data!");
});
} else {
let newData = { id: uid(), name: formData.name, telp: formData.telp };
data.push(newData);
axios.post("http://localhost:3000/contacts", newData).then((res) => {
alert("Data telah disimpan cok!");
});
}
// tambah kontak yee
setIsUpdate({id: null, status: false});
setContacts(data);
setFormData({ name: "", telp: ""});
}
function handleEdit(id) {
let data = [...contacts];
let foundData = data.find((contact) => contact.id === id);
setFormData({ name: foundData.name, telp: foundData.telp});
setIsUpdate({id: id, status: true});
}
function handleDelete(id) {
let data = [...contacts];
let filteredData = data.filter((contact) => contact.id !== id);
axios.delete('http://localhost:3000/contacts/${id}').then((res) => {
alert("Data telah dihapus");
});
setContacts(filteredData);
}
return (
<div className="App">
<h1 className="px-3 py-3">My Contact List</h1>
<form onSubmit={handleSubmit} className="px-3 py-4">
<div className="form-group">
<label htmlFor="">Name</label>
<input type="text"
className="form-control"
onChange={handleChange}
value={formData.name}
name="name" />
</div>
<div className="form-group mt-3">
<label htmlFor="">No. Telp</label>
<input type="text"
className="form-control"
onChange={handleChange}
value={formData.telp}
name="telp" />
</div>
<div>
<button type="submit" className="btn btn-primary w-100 mt-3">
Save
</button>
</div>
</form>
<List handleDelete={handleDelete} handleEdit={handleEdit} data={contacts} />
</div>
);
}
export default App;
The list component:
import React from "react";
export default function List({data,handleEdit,handleDelete}) {
return (
<div className="list-group">
{
data.map((contact) => {
return (
<div className="list-group-item list-group-item-action">
<div className="d-flex w-100 justify-content-between">
<h5 className="mb-1">{contact.name}</h5>
<div>
<button onClick={() => handleEdit(contact.id)} className="btn btn-sm btn-link">Edit</button>
<button onClick={() => handleDelete(contact.id)} className="btn btn-sm btn-link">Del</button>
</div>
</div>
<p className="mb-1">{contact.telp}</p>
</div>
);
})}
</div>
);
}
I follow the tutorial, the code is like this, i checked it in so many times. But still it does not configure well into json-server like what i see on youtube.

Getting Error 400 (Bad Request) When I Submit Data in MERN

I'm trying to save products in my MERN project. When I try to submit data I get this message
http://localhost:8000/api/product/create/5f4e7732333b2b21ec06a9f5 400 (Bad Request) and when I checked a response in the network it gives {"error":""} no error message it gives. Please review my code and guide me.
AddProduct.js
import React, {useState, useEffect} from 'react';
import Layout from '../core/Layout';
import {isAuthenticated} from '../auth';
import {createProduct, getCategories} from './apiAdmin';
const AddProduct = () => {
const [values, setValues] = useState({
name: '',
description: '',
price: '',
categories: [],
category: '',
shipping: '',
quantity: '',
photo: '',
loading: false,
error: '',
createProduct: '',
redirectToProfile: false,
formData: ''
});
const {user, token} = isAuthenticated();
const {
name,
description,
price,
categories,
category,
shipping,
quantity,
loading,
error,
createProducts,
redirectToProfile,
formData
} = values;
const init = () => {
getCategories().then(data => {
if(data.error){
setValues({...values, error: data.error})
} else{
setValues({...values, categories: data.data, formData: new FormData()});
}
});
};
useEffect(() => {
init();
}, []);
const handelChnage = name => event => {
const value = name === 'photo' ? event.target.files[0] : event.target.value
formData.set(name, value)
setValues({...values, [name]: value})
};
const clickSubmit = (event) => {
event.preventDefault();
setValues({...values, error: '', loading: true});
createProduct(user._id, token, formData).then(data =>{
if(data.error){
setValues({...values, error: data.error})
} else{
setValues({
...values,
name: '',
description: '',
photo: '',
price: '',
quantity: '',
loading: false,
createProduct: data.name
});
}
});
};
const newPostForm = () => (
<form className="mb-3" onSubmit={clickSubmit}>
<h4>Post Photo</h4>
<div className="form-group">
<label className="form-group">
<input onChange={handelChnage('photo')} type="file" name="photo" accept="image/*" />
</label>
</div>
<div className="form-group">
<label className="text-muted">Name</label>
<input onChange={handelChnage('name')} type="text" className="form-control" value={name} />
</div>
<div className="form-group">
<label className="text-muted">Description</label>
<textarea onChange={handelChnage('description')} className="form-control" value={description} />
</div>
<div className="form-group">
<label className="text-muted">Price</label>
<input onChange={handelChnage('price')} type="number" className="form-control" value={price} />
</div>
<div className="form-group">
<label className="text-muted">Category</label>
<select onChange={handelChnage('category')} className="form-control" >
<option>Please Select</option>
{categories && categories.map((c,i) => (
<option key={i} value="{c._id}">
{c.name}
</option>
))}
</select>
</div>
<div className="form-group">
<label className="text-muted">Shipping</label>
<select onChange={handelChnage('shipping')} className="form-control" >
<option>Please Select</option>
<option value="0">No</option>
<option value="1">Yes</option>
</select>
</div>
<div className="form-group">
<label className="text-muted">Quantity</label>
<input onChange={handelChnage('quantity')} type="number" className="form-control" value={quantity} />
</div>
<button className="btn btn-outline-primary">Create Category</button>
</form>
);
const showError = () =>{
return(
<div className="alert alert-danger" style={{display: error ? '' : 'none'}}>
{error}
</div>
);
};
const showSuccess = () =>{
return(
<div className="alert alert-info" style={{display: createProducts ? '' : 'none'}}>
<h2>product is created!</h2>
</div>
);
};
const showLoading = () =>
loading && (
<div className="alert alert-info">
<h2>Loading...</h2>
</div>
);
return(
<Layout title="Add New Product" description={`Welcome ${user.name}!`} className="container-fluid" >
<div className="row">
<div className="col-8 offset-md-2">
{showLoading()}
{showSuccess()}
{showError()}
{newPostForm()}
</div>
</div>
</Layout>
);
};
export default AddProduct;
apiAdmin.js
export const createProduct = (userId, token, product) =>{
//console.log(name, photo, description, price, category, shipping, quantity);
const url = `http://localhost:8000/api/product/create/${userId}`;
//console.log(url);
return fetch(url, {
method: "POST",
headers:{
Accept: 'application/json',
Authorization : `Bearer ${token}`
},
body: product
})
.then(response => {
return response.json();
})
.catch(err =>{
console.log(err);
});
};
please help me
Thanks in advance
const [values, setValues] = useState({
name: '',
description: '',
price: '',
categories: [],
category: '',
shipping: '',
quantity: '',
photo: '',
loading: false,
error: '',
createdProduct: '', -> edit
redirectToProfile: false,
formData: ''
});
const {user, token} = isAuthenticated();
const {
name,
description,
price,
categories,
category,
shipping,
quantity,
loading,
error,
createdProduct, -> edit
redirectToProfile,
formData
} = values;

react login register form sends empty data

I have a backend setup with node and express and frontend is React + Redux
The backend works well. I tested it all with insomina and i can successfully register a user and login.
On the front end side, everything looks ok except for the fact that when i try to login or register a user, it tells me that the input fields are required, which means that it sends an empty object to my backend. I also have a message in the console saying that componentWillReceiveProps(nextProps) is depricated and suggests using getDerivedStateFromProps instead. The issue is that i am new to React and have no idea how to convert that block. Can someone tell me? Is that even why the form sends an empty object?
EDIT: Added github repo for complete code
https://github.com/onidemon/wh-evcharge
Register.js is below, both login and Register have a componentWillReceiveProps block which i think might be causing the issue. Not sure how to convert them to getDerivedStateFromProps if that is even the cause of the problem.
import React, { Component } from "react";
import { Link, withRouter } from "react-router-dom";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { registerUser } from "../../actions/authActions";
import classnames from "classnames";
class Register extends Component {
constructor() {
super();
this.state = {
name: "",
email: "",
password: "",
password2: "",
errors: {}
};
}
componentDidMount() {
// If logged in and user navigates to Register page, should redirect them to dashboard
if (this.props.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
onChange = e => {
this.setState({ [e.target.id]: e.target.value });
};
onSubmit = e => {
e.preventDefault();
const newUser = {
name: this.state.name,
email: this.state.email,
password: this.state.password,
password2: this.state.password2
};
this.props.registerUser(newUser, this.props.history);
};
render() {
const { errors } = this.state;
return (
<div className="container">
<div className="row">
<div className="col s8 offset-s2">
<Link to="/" className="btn-flat waves-effect">
<i className="material-icons left">keyboard_backspace</i> Back to
home
</Link>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<h4>
<b>Register</b> below
</h4>
<p className="grey-text text-darken-1">
Already have an account? <Link to="/login">Log in</Link>
</p>
</div>
<form noValidate onSubmit={this.onSubmit}>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.name}
error={errors.name}
id="name"
type="text"
className={classnames("", {
invalid: errors.name
})}
/>
<label htmlFor="name">Name</label>
<span className="red-text">{errors.name}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.email}
error={errors.email}
id="email"
type="email"
className={classnames("", {
invalid: errors.email
})}
/>
<label htmlFor="email">Email</label>
<span className="red-text">{errors.email}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password}
error={errors.password}
id="password"
type="password"
className={classnames("", {
invalid: errors.password
})}
/>
<label htmlFor="password">Password</label>
<span className="red-text">{errors.password}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password2}
error={errors.password2}
id="password2"
type="password"
className={classnames("", {
invalid: errors.password2
})}
/>
<label htmlFor="password2">Confirm Password</label>
<span className="red-text">{errors.password2}</span>
</div>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<button
style={{
width: "150px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
type="submit"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
>
Sign up
</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
Register.propTypes = {
registerUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(
mapStateToProps,
{ registerUser }
)(withRouter(Register));
Login.js is below
import React, { Component } from "react";
import { Link } from "react-router-dom";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { loginUser } from "../../actions/authActions";
import classnames from "classnames";
class Login extends Component {
constructor() {
super();
this.state = {
email: "",
password: "",
errors: {}
};
}
componentDidMount() {
// If logged in and user navigates to Login page, should redirect them to dashboard
if (this.props.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
if (nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
onChange = e => {
this.setState({ [e.target.id]: e.target.value });
};
onSubmit = e => {
e.preventDefault();
const userData = {
email: this.state.email,
password: this.state.password
};
this.props.loginUser(userData);
};
render() {
const { errors } = this.state;
return (
<div className="container">
<div style={{ marginTop: "4rem" }} className="row">
<div className="col s8 offset-s2">
<Link to="/" className="btn-flat waves-effect">
<i className="material-icons left">keyboard_backspace</i> Back to
home
</Link>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<h4>
<b>Login</b> below
</h4>
<p className="grey-text text-darken-1">
Don't have an account? <Link to="/register">Register</Link>
</p>
</div>
<form noValidate onSubmit={this.onSubmit}>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.email}
error={errors.email}
id="email"
type="email"
className={classnames("", {
invalid: errors.email || errors.emailnotfound
})}
/>
<label htmlFor="email">Email</label>
<span className="red-text">
{errors.email}
{errors.emailnotfound}
</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password}
error={errors.password}
id="password"
type="password"
className={classnames("", {
invalid: errors.password || errors.passwordincorrect
})}
/>
<label htmlFor="password">Password</label>
<span className="red-text">
{errors.password}
{errors.passwordincorrect}
</span>
</div>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<button
style={{
width: "150px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
type="submit"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
>
Login
</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
Login.propTypes = {
loginUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(
mapStateToProps,
{ loginUser }
)(Login);
EDIT: Added AuthActions.js
import axios from "axios";
import setAuthToken from "../utils/setAuthToken";
import jwt_decode from "jwt-decode";
import { GET_ERRORS, SET_CURRENT_USER, USER_LOADING } from "./types";
// Register User
export const registerUser = (userData, history) => dispatch => {
axios
.post("/api/users/register", userData)
.then(res => history.push("/login"))
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
// Login - get user token
export const loginUser = userData => dispatch => {
axios
.post("/api/users/login", userData)
.then(res => {
// Save to localStorage
// Set token to localStorage
const { token } = res.data;
localStorage.setItem("jwtToken", token);
// Set token to Auth header
setAuthToken(token);
// Decode token to get user data
const decoded = jwt_decode(token);
// Set current user
dispatch(setCurrentUser(decoded));
})
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
// Set logged in user
export const setCurrentUser = decoded => {
return {
type: SET_CURRENT_USER,
payload: decoded
};
};
// User loading
export const setUserLoading = () => {
return {
type: USER_LOADING
};
};
// Log user out
export const logoutUser = () => dispatch => {
// Remove token from local storage
localStorage.removeItem("jwtToken");
// Remove auth header for future requests
setAuthToken(false);
// Set current user to empty object {} which will set isAuthenticated to false
dispatch(setCurrentUser({}));
};
I looked on your github project.
If I am not mistaken I haven't seen you using in your server the bodyparser.json() function. You only use the bodyParser.urlencoded(), which convert url parameters into processable objects.
Add as well bodyParser.json(), then you would get the incoming data from the body of the request as well. Then you should have it I believe.

Resources