States in react not getting updated - node.js

Inside the verifyPassword function when I am trying to update the state of user using setUser, it is not updating. Therefore the values of input remain the same and also when I console log user it is empty.
I have also tried by first storing the res object from .done method in another variable and then update the state, but that didn't work too.
below is the code.
import React , {useState} from "react";
import $ from "jquery";
function ChangeDetails(props){
var [pass , setPass] = useState("");
var [user , setUser] = useState({
name:"",
phone:"",
email:""
});
var [auth ,setAuth] = useState(false);
function passChange(e){
let password = e.target.value;
setPass(password);
}
function verifyPassword(event){
event.preventDefault();
$.post("http://localhost:4000/details" , {username: sessionStorage.getItem("User") , password: pass})
.done((res)=>{
let {name , phone, email} = res;
console.log(name);
setUser=({
name:name,
phone:phone,
email:email
})
console.log(user);
console.log(res);
setAuth(true);
})
.fail(e=>{console.log(e);})
}
function handleChange(e){
let {name , value} = e.target;
setUser(prevValue=>{
return {
...prevValue,
[name] : value
}
})
}
return (
<div>
<h1>Change Your Details here #{sessionStorage.getItem("User")}</h1>
{!auth && <form onSubmit={verifyPassword}>
<h2>Verify by entering Password</h2>
<input onChange={passChange} value={pass} type="password" name="password" />
<button>Submit</button>
</form>}
{auth && <form>
<label>Name:
<input type="text" onChange={handleChange} value={user.name} name="name" id="name" /></label><br />
<label>Phone Number:
<input type="text" onChange={handleChange} value={user.phone} name="phone" id="phone" /></label><br />
<label>Email:
<input type="email" onChange={handleChange} value={user.email} name="email" id="email" /></label><br />
<button>Change</button>
</form>}
</div>
);
}
export default ChangeDetails;

you got typo on setUser within verifyPassword function
you typed setUser=
it should be setUser()

Because setUser is a funtion to update state. Use
setUser({
name:name,
phone:phone,
email:email
})
instead of
setUser = ({
name:name,
phone:phone,
email:email
})

Related

how to post form data to the server backend

Form.js
import "./form.css";
import React, {useEffect,useState} from "react";
import {addBeauty,deleteB} from "./beauty";
import Modal from "./Modal";
import axios from 'axios';
export default function CreateForm() {
const [Name, setName] = useState("");
const [Intro, setIntro] = useState("");
const [isOpen, setIsOpen] = useState();
const [backendData, setBackendData] = useState([{}]);
useEffect(()=>{
fetch("http://localhost:5000/api").then(
response=>response.json()
).then(
data=>{ setBackendData(data)}
)
},[]);
const handleSubmit = (event)=>{
event.preventDefault();
axios.post("http://localhost:5000/api",{
id: userList[userList.length - 1].id + 1, Name:Name, Introduction:Intro
}).then(res=>{
console.log(res.data);
})
}
return (
<div className="container">
<form className="add" onSubmit={handleSubmit} >
<h2>User</h2>
<label htmlFor= "name">Name</label>
<input type="text" value={Name}
onChange={(event) => {setName(event.target.value);}}/>
<label htmlFor= "Intro">Introduction</label>
<input type="text" value={Intro}
onChange={(event) => {setIntro(event.target.value);}}/>
<p></p>
<p></p>
<div className = "press">
<button id = "1" type="submit">
Add Beauty
</button>
<button id = "2"
onClick={clearForm}
>
Clear Form
</button>
</div>
</form>
<br></br>
<br></br>
<br></br>
<div className="display">
{(typeof userData.user1 === 'undefined')?(
<h1>Loading</h1>):(
backendData.user1.map((user,i)=>{
return (
<div>
<h1> {user.Name}</h1>
<button onClick={()=>{
setIsOpen(user.id);
}}>View in popup</button>
<Modal open={isOpen === user.id} onClose={()=>setIsOpen(undefined)}>
<h3> {User.Introduction}</h3>
</Modal>
</div>
);})
)}
</div>
</div>
);
}
Server.js
const express = require('express');
const app = express();
const cors=require("cors");
const corsOptions ={
origin:'*',
credentials:true, //access-control-allow-credentials:true
optionSuccessStatus:200,
}
app.use(cors(corsOptions)) // Use this after the variable declaration
app.get("/api",(req,res)=> {
res.json({"user1":[
{
id: 1,
Name: "Isabella",
},
{
id:2,
Name: "Catalina
}
]})
});
app.listen(5000,()=>{
console.log("Server started on port 5000");
})
I create a from using react. And I try to send the formdata to backend and insert the formdata into the data stored at backend using axios.post. But it doesn't work. I know it's because I didn't add the prefix of backend data "user1" in axios.post. But I am not sure how to do that. Could anyone help me with this?
You have not created the route on the server correctly. You have opened a route for GETting "/api" but you need to open a route for POSTing
Replace this line:
app.get("/api",(req,res)=> {
with
app.post("/api",(req,res)=> {
Hi Here you need to create one route for post API as below
app.post("/api",(req,res)=> {
console.log(req.body) //here you got the requested data.
res.send("Success !");
});

How I can get check box value and button value in this stuation? Can any one have suggest

I want to get the value of "gender" checkbox and "button" in div rect1,and react 2 to male,female and customer,shop. How I can get it?
I was try to gender == "male" or "female" but it return false
What I need change ?
function Register() {
const [username,setUsername]= useState("");
const [password,setPassword]= useState("");
const [email,setEmail]= useState("");
const [phone,setPhone]= useState("");
const [gender,setGender]= useState("");
const [role,setRole]= useState("");
const [error, setError]= useState("");
let history = useHistory();
const register = (e) => {
e.preventDefault();
axiox.post("http://localhost:5001/api/auth/register",
{username,
email,
phone,
password,
gender,
role,
}).then((response)=> {
console.log("response", response)
localStorage.setItem("login", JSON.stringify({
userLogin: true,
token: response.data.access_token,
}));
setError("");
setUsername("");
setPassword("");
setGender(");
setRole"();
history.push("/login");
}).catch(error =>setError(error.response.data.message));
};
return (
<input type="radio" name="gender" value={male} onChange={(e)=> setGender(e.target.value)}/>
<label for="male"></label>
<span>Male</span>
<input type="radio" name="gender" value={female} onChange={(e)=> setGender(e.target.value)}/>
<label for="female"></label>
<span>Female</span>
</div>
<div class="rect1">
<button class="button" type="button" value={shop} onChange={(e)=> setRole(e.target.value)}><img src={process.env.PUBLIC_URL + `/Images/shop 1.png`} /></button>
</div>
<div class="rect2">
<button class="button" type="button" value={customer} onChange={(e)=> setRole(e.target.value)}> <img src={process.env.PUBLIC_URL + `/Images/take-away.png`} /></button>
Thank for helping me
change state to boolean call it isMale
const [isMale , setIsMale]=useState(false)
than into return make
<input type="radio" name="gender" value={male} onChange={()=>
setGender(true)}/>
<label for="male"></label>
<span>Male</span>
<input type="radio" name="gender" value={female} onChange={()=> setGender(false)}/>
<label for="female"></label>
<span>Female</span>

Error: data and salt arguments required [creating new users]

I am a back-end beginner and just want to implement the CRUD functions for my homepage and try to send the user data to my database with a usual sign-up template. However, I keep getting the following error message: "Error: data and salt arguments required".
This is the code for creating a new user:
controller.js
require('dotenv').config()
var UserDB = require('../model/model');
var UserDB2 = require('../model/testmodel');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
const salt = 10;
exports.create=(req,res)=>{
//validate
if(!req.body){
res.status(400).send({message:'Empty'});
return;
}
//hash password
const hashedPassword= bcrypt.hashSync(req.body.password,salt)
//
//new user
const user = new UserDB({
name: req.body.name,
email: req.body.email,
password: password
})
//save database
user
.save(user)
.then(data => {
res.redirect('/signup')
})
.catch(err =>{
res.status(500).send({
message: err.message || "Mars Attacks !"
})
});
}
signup.ejs
<body>
<div class="Wrapklasse">
<div class="derKoerper">
<div class="dieKoerper dieKoerper-step-1 is-showing">
<div class="title">Sign Up</div>
<form action="/api/users" method="POST" id="add_user">
<input type="text" placeholder="Username*" required id="username" />
<input type="email" placeholder="E-Mail*" required id="email" />
<input type="password" placeholder="Password*" required id="password" />
<input type="con-password" placeholder="Confirm Password*" />
<div class="text-center">
<span id="SignUp"><img src=/img/knight.jpg alt="knight" style="width:35%" class="das_icon"></span>
<input type="submit" />
</div>
</form>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous"></script>
<script> src="/js/index.js"</script>
</body>
index.js
$("#add_user").submit(function(event){
alert("Success!");
})
router.js
const express = require('express');
const route = express.Router();
const services = require ('../services/render');
const controller = require ('../controller/controller');
const jwt = require('jsonwebtoken');
//for use
route.get('/',services.homeRoutes);
route.get('/signup',services.signup);
route.get('/forum',services.forum);
route.get('/unterforum',services.unterforum);
route.get('/beitrag',services.beitrag);
route.get('/beitrag_erstellen',services.beitrag_erstellen);
//API
route.post('/api/users',controller.create);
route.get('/api/users',controller.find);
route.put('/api/users/:id',controller.update);
route.delete('/api/users/:id',controller.delete);
module.exports=route;
Unfortunately, I don't know what the fault could be.
Make sure you have defined salt rounds ("Salt" variable) and also make sure that req.body.password is not undefined

I am getting a Warning: A component is changing an uncontrolled input of type text to be controlled

I building a simple todo app using the MERN stack with router and able to get it going except the edit part. I have 3 routes, the "Todos" page where i use axios to get the data from my express server route. The "Add" page for create new todo and the "Edit" page for editing and deleting. Here's my todos page where each todo has a button that takes the id as a url parameter unto the Edit page.
That little pencil/paper icon on each todo is a button link that get's the ID on click. Here's my Edit page with the data.
The warning:
Here's my Todos page i'm using a custom hook to fetch the data from express server route:
import React from 'react';
import useGetAPI from '../custom_hooks/useGetAPI';
import Todo from './todo_item/Todo';
const Todos = () =>{
const data = useGetAPI('http://localhost:4000');
return (
<div className="page">
<div className="page-header">
<h1>Todo Lists</h1>
</div>
<div className="page-content">
<ul className="todo-list">
{
data.map((todo)=><Todo todo={todo} key={todo._id}/>)
}
</ul>
</div>
</div>
);
}
export default Todos;
Here's my custom hooks for fetching data - used in Todos.
import {useState,useEffect} from 'react';
import axios from 'axios';
const useGetAPI = (url)=>{
const [data,setData] = useState([]);
useEffect(()=>{
const fetchData = async ()=>{
const response = await axios.get(url);
const data = [...response.data];
const error = response.error;
if(error)
console.log(error)
else{
console.log(data);
setData(data);
}
};
fetchData();
},[url])
return data;
}
export default useGetAPI;
Here's my Edit Page
import React,{useState, useEffect, useContext, useCallback} from 'react';
import useGetApiWithParams from '../custom_hooks/useGetApiWithParams';
import {FaTelegramPlane} from 'react-icons/fa';
import axios from 'axios';
import { matchPath } from 'react-router'
const EditTodo = (props) =>{
const todoID = props.match.params.id;
const [todo,setTodo] = useState(null);
const responseData = useGetApiWithParams('http://localhost:4000/edit',todoID);
console.log(`Todo id: ${todoID}`);
/* Set default data from database */
useEffect(()=>{
setTodo(responseData);
},[responseData,setTodo]);
const [description,setDescription] = useState('');
const [responsible,setResponsible] = useState('');
const [priority,setPriority] = useState('');
const [completed,setCompleted] = useState(false);
const handleDescription = useCallback((e)=>{
setDescription(e.target.value);
},[setDescription]);
const handleResponsible = useCallback((e)=>{
setResponsible(e.target.value);
},[setResponsible]);
const handlePriority = useCallback((e)=>{
setPriority(e.target.value);
},[setPriority]);
const handleCompleted = useCallback((e)=>{
setCompleted(!completed);
},[completed,setCompleted])
const handleSubmit = useCallback((e)=>{
e.preventDefault();
console.log('Form submitted');
console.log(`Description ${description}`);
console.log(`Description ${responsible}`);
console.log(`Description ${priority}`);
console.log(`Description ${completed}`);
const updatedTodo = {
description,
responsible,
priority,
completed: false
}
axios.put(`http://localhost/4000/edit/${props.match.params.id}`, updatedTodo)
.then(res=>console.log(res.data))
.catch(function (error) {
console.log(error);
});
},[description,responsible,priority,completed,props.match.params.id]);
return (
<div className="page">
<div className="page-header">
<h1>Edit Todo</h1>
</div>
<div className="page-content">
<form id="edit-todo-form" className="todo-form" onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="description">Description:</label>
<input id="description" type="text" className="form-control" onChange={handleDescription} value={responseData.description} />
</div>
<div className="form-group">
<label htmlFor="responsible">Responsible:</label>
<input id="responsible" type="text" className="form-control" onChange={handleResponsible} value={responseData.responsible} />
</div>
<div className="form-group">
<label htmlFor="priorities">Priorities:</label>
<div id="priorities" className="form-radios">
<label htmlFor="radio1" className="radio-label">
<input name="priorityOptions" type="radio" id="radio1" value={responseData.priority} checked={priority === 'Low'} onChange={handlePriority}/>
<span className="radiomark"></span>
<span className="radiotext">Low</span>
</label>
<label htmlFor="radio2" className="radio-label">
<input type="radio" id="radio2" value={responseData.priority} checked={priority === 'Medium'} onChange={handlePriority}/>
<span className="radiomark"></span>
<span className="radiotext">Medium</span>
</label>
<label htmlFor="radio3" className="radio-label">
<input type="radio" id="radio3" value={responseData.priority} checked={priority === 'High'} onChange={handlePriority}/>
<span className="radiomark"></span>
<span className="radiotext">High</span>
</label>
</div>
</div>
<div className="form-group">
<label htmlFor="todo_completed">Status:</label>
<div id="todo_completed">
<label htmlFor="checkcompleted" className="check-label">
<input type="checkbox" id="checkcompleted" value={responseData.completed} onChange={handleCompleted}/>
<span className="checkmark"></span>
<span className="checktext">Completed</span>
</label>
</div>
</div>
<div className="form-group">
<button type="submit" className="form-btn"><FaTelegramPlane />Save Changes</button>
</div>
</form>
</div>
</div>
);
}
export default EditTodo;
Here's my custom hook for fetching data based on the Todo ID i get from the url:
import { useState,useEffect } from 'react';
import axios from 'axios';
const useGetApiWithParams = (url,params)=>{
const [data,setData] = useState([]);
useEffect(()=>{
const fetchData = async ()=>{
const response = await axios.get(`${url}/${params}`);
const data = response.data;
const error = response.error;
if(error)
console.log(`Error: ${error}`)
else{
console.log(...data);
setData(...data);
}
};
fetchData();
},[url,params])
return data;
}
export default useGetApiWithParams;
And the url with id param from MongoDB:
How to solve this? I tried the placeholder and set it's value to the response data from api but it only works for text boxes, what about the radio buttons and checkboxes? They don't seem to set the default value. For example the radio button for setting the priority value={responseData.priority} doesn't set the value as you can see here:
What i would like to happen is: from the Todos page on clicking the edit button, the edit page with a form already filled with values based on the todo id from the url parameter and be able to edit the values as well. Need help, thanks!

Axios POST request doesn't work

I'm using Axios to send POST request to Node.js server but it doesn't work. Do you have any idea how to resolve it?
My code is shown below:
server.js:
app.post('/registration', (req, res) => {
console.log(req.body);
});
my class:
export default class Registration extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = {}
}
handleSubmit (e) {
e.preventDefault;
axios.post('/registration', {name: document.getElementById('name') }).then(res => {
console.log(res);
})
}
render() {
return (<form className="registrationForm">
<input type="text" name="name" id="name" required="required" placeholder="name"/>
<br/>
{/*<input type="text" name="email" required="required" placeholder="email"/>
<br/>
<input type="number" name="phoneNumber" required="required" placeholder="phoneNo"/>
<br/>
<input type="password" name="password" required="required" placeholder="pass"/>
<br/> */}
<button className="registerButton" onClick={this.handleSubmit}>register</button>
</form>)
};
}
You have various problems in your code
preventDefault is method. You need to call it
I doubt you want to send DOM element to the server
You want to handle network failure using catch
Corrected handleSubmit should look like this
handleSubmit (e) {
e.preventDefault(); // NB
const data = {name: document.getElementById('name').value /* NB */ };
axios.post('/registration', data).then(res => {
console.log(res);
}).catch(console.error) // now you could see what the actual problem is
}
Also it is generally not adviced to use DOM lookup methods in your React up. You should better keep a ref to the input.
<input ... ref={input => this.name = input}/>
const data = {name: this.name.value };
The problem was for just a single line that I didn't write in my server side application.
The only thing to check is to put the following line after requiring the body-parser in your file.
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));

Resources