React - Axiost put request get weird result - reactjs

I am working on my project with a backend.
and currently working on a component which performs a put request to update details of a customer bean. however, I am experiencing a weird behavior.
Component:
function UpdateCustomer(props): JSX.Element {
const history = useHistory();
const [skipCount, setSkipCount] = useState(true);
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
async function formData() {
try {
const response = await axios.put<CustomerModel>(globals.adminUrls.updateCustomer + props.location.state.id, {
firstName: firstName,
LastName: lastName,
email: email,
password: password
});
const updated = response.data;
store.dispatch(customerUpdatedAction(updated));
notify.success(CUSTOMER_SccMsg.CUSTOMER_UPDATED)
}
catch (err) {
notify.error(err);
}
}
const handleSubmit = (e) => {
e.preventDefault();
formData();
}
useEffect(() => {
if (skipCount) setSkipCount(false);
if (!skipCount) formData();
}, []);
return (
<div className="custom-field">
<h2>Update Customer</h2>
<div>
<form onSubmit={handleSubmit} >
<label>First name</label>
<input type="text" name="firstName" onChange={(e) => { setFirstName(e.target.value) }} />
<label>Last name</label>
<input type="text" name="lastName" onChange={(e) => { setLastName(e.target.value) }} />
<label>Email</label>
<input type="text" name="email" onChange={(e) => { setEmail(e.target.value) }} />
<label>Password</label>
<input type="text" name="password" onChange={(e) => { setPassword(e.target.value) }} />
<input type="submit" name="submit" />
</form>
</div>
</div>
);
}
export default UpdateCustomer;
backend Service:
public void updateCustomer(#Valid int id, CustomerDto customerDto) throws DoesNotExistException {
Customer customerDao = customerMapper.toDao(customerDto);
if (!custRepo.existsById(id))
throw new DoesNotExistException("Customer does not exist");
custRepo.saveAndFlush(customerDao);
backend Controller:
#PutMapping(value = "update/customer/{id}")
#ResponseStatus(HttpStatus.ACCEPTED)
#Override
public void updateCustomer(#PathVariable int id, #RequestBody CustomerDto customerDto) throws DoesNotExistException {
adminService.updateCustomer(id, customerDto);
}
Result I am getting:
I am able to save all fields into a const apart from lastName for some reason. it behaves exactly like the other fields. however, this specific field sends null to server while other fields send the input values.
Instead of performing an update to bean it just adds this as a seperate bean.
Why is this weird?
I have an identical component for updating a company and it seems to work just fine. why does this component behave differently?
Hope someone can put a hand on the problem.
Thanks.

You put LastName in the request body, check below image:
I think there is a mistake here, it looks like should be lastName, not LastName.

Related

How do I store an image in react useState

I'm trying to add a form in which users can add text and images which is then going to be stored on the mongodb database. As of right now, I'm trying to add a section in the form where users can add images. I'm trying to figure out a way to store an image that the user uploads and send it to the backend (I'm using MERN stack).
This is my code that deals with the form, in terms of getting user input and sending it to the backend:
import { useState } from "react";
import { adminSDGOptions } from "./AdminCategoryLists";
import { adminAssingmentOptions } from "./AdminCategoryLists";
import { keywordsOptions } from "../FilterComponents/CategoryArrays/KeywordsOptions";
import Multiselect from "multiselect-react-dropdown"
import Select from 'react-select';
const ProjectAdminForm = () => {
// Adding basic info
const [sdg, setSDG] = useState('')
const [goal, setGoal] = useState('')
const [orginization, setOrginization] = useState('')
const [source, setSource] = useState('')
const [location, setLocation] = useState('')
const [published, setPublished] = useState('')
const [website_url, setWebsiteURL] = useState('')
const [assignment_type, setAssignmentType] = useState('')
const [sharepoint_link, setSharepointLink] = useState('')
const [statement, setStatement] = useState('')
const [preview_img, setPreviewImg] = useState([])
const [error, setError] = useState(null)
// Adding keywords
const [keywords, setKeywords] = useState([]);
const handleSubmit = async (e) => {
e.preventDefault() // Prevents refresh of page from happening
console.log('button clicked')
const project = {sdg, goal, orginization, source, location, published, website_url, assignment_type, keywords, sharepoint_link, statement, preview_img}
console.log(project)
// Sending form response to backend
const response = await fetch('/api/projects', {
method: 'POST',
body: JSON.stringify(project),
headers: {
'Content-Type': 'application/json'
}
})
const json = await response.json
// Checking for error
if (!response.ok) {
setError(json.error)
}
if (response.ok) {
// Reset form inputs back to empty string
setSDG('')
setGoal('')
setOrginization('')
setSource('')
setLocation('')
setPublished('')
setWebsiteURL('')
setAssignmentType('')
setKeywords([])
setSharepointLink('')
setStatement('')
setError(null)
alert('Project added!')
console.log('new project added', json)
}
}
return (
<form className="create project-form" onSubmit={handleSubmit}>
<h2 style={{"textAlign": "center"}}>Add a New Project</h2>
<hr></hr>
<label>Sustainable Development Goal:</label>
<Select
className="basic-single"
classNamePrefix="select"
placeholder="Select"
name="color"
options={adminSDGOptions}
onChange={(selection) => setSDG(selection.value)}
required
/>
<label>Description:</label>
<input
type="text"
onChange={(e) => setGoal(e.target.value)}
value={goal}
required
/>
<label>OPTIONAL - Organization:</label>
<input
type="text"
onChange={(e) => setOrginization(e.target.value)}
value={orginization}
/>
<label>OPTIONAL - Source:</label>
<input
type="text"
onChange={(e) => setSource(e.target.value)}
value={source}
/>
<label>OPTIONAL - Location:</label>
<input
type="text"
onChange={(e) => setLocation(e.target.value)}
value={location}
/>
<label>Published (YEAR ONLY):</label>
<input
type="text"
onChange={(e) => setPublished(e.target.value)}
value={published}
required
/>
<label>OPTIONAL - Website URL:</label>
<input
type="text"
onChange={(e) => setWebsiteURL(e.target.value)}
value={website_url}
/>
<label>Assignment Type:</label>
<Select
className="basic-single"
classNamePrefix="select"
placeholder="Select"
name="color"
options={adminAssingmentOptions}
onChange={(selection) => setAssignmentType(selection.value)}
required
/>
<hr></hr>
<label>Enter Keyword(s):</label>
<Multiselect
className="multiselect-admin"
isObject={false}
onRemove={(selection) => setKeywords(selection)}
onSelect={(selection) => setKeywords(selection)}
options={keywordsOptions}
required
/>
<hr></hr>
<label>OPTIONAL - Statement (ONLY Assessment Ideas and Discussion Topics):</label>
<input
type="text"
onChange={(e) => setStatement(e.target.value)}
value={statement}
/>
<label>OPTIONAL - Qualtrics Link (ONLY Mini Case Study):</label>
<input
type="text"
onChange={(e) => setSharepointLink(e.target.value)}
value={sharepoint_link}
/>
// THIS IS THE SECTION I'M TRYING TO ADD AND AM NOT SURE HOW TO GO ABOUT DOING SO
<label>OPTIONAL - Preview image:</label>
<input
type="file"
name="preview_img"
accept="image/*"
onChange={(e) => setPreviewImg(e.target.value)}
/>
<div className="add-proj">
<button>Add Project</button>
</div>
{error && <div className="error">{error}</div>}
</form>
)
}
export default ProjectAdminForm
The main thing I'm trying to get working is the preview_img stuff, I'm able to ask the user for an image through <input/> but then when I store itin my useState which is set up like this const [preview_img, setPreviewImg] = useState([]), it doesn't save the actual image, rather a string which looks like this:
preview_img: "C:\\fakepath\\banner2 (2).jpg"
I'm not sure how to save the actual image and then send it to the backend in my handleSubmit function since it appears I can't just include the state name (preview_img) in the object I'm sending to the backend.
You can reach and upload the image in onChange function. If you want to use it by accessing local url, you can create and store its local url in a state.
const [imageURL,setImageURL] = useState()
onChange={(event) => {
let file = event.target.files[0]
yourUploadFunction(file, url)
setImageURL(URL.createObjectURL(file))
}}

How to create a controller method for registration that saves user to a mySQL database

I have a login/registration form in React and I am trying to connect it to a Spring restful endpoint. I’m using a persistent user class and just need basic authentication.
Below is the frontend portion so far. However, I am also having difficulty with my authentication controllers in Spring Boot so I just deleted them.
Can anyone help with a very basic controller method for registration. I’d like one that saves the user to the database (mySQL) via a userRepository and also authenticates login.
const Login = () => {
const [registration, setRegistration] = useState("true");
const [email, setEmail] = useState("");
const [regPwd, setRegPwd] = useState("");
const [regUsername, setRegUsername] = useState("");
const [logUsername, setLogUsername] = useState("");
const [logPwd, setLogPwd] = useState("");
const handleRegSubmit = async (e) => {
e.preventDefault();
const regUser = {
email: email,
username: regUsername,
password: regPwd
}
try {
const response = await axios.post('http://localhost:8080/registration',
{ regUser })
}
catch (error) {
}
}
const handleLogSubmit = async (e) => {
e.preventDefault();
const logUser = {
username: logUsername,
password: logPwd
}
try {
const response = await axios.post('http://localhost:8080/login',
{ logUser })
}
catch (error) {
}
}
const registerForm = (
<form onSubmit={handleRegSubmit} id="Regform">
<h1 className="ky">Kale Yeah!</h1>
<label htmlFor="Email">Email</label>
<input
type="email"
placeholder="Email"
value={email}
onChange = {(e) => setEmail(e.target.value)}
required />
<label htmlFor="username">Username</label>
<input
type="text"
placeholder="Username"
value={regUsername}
onChange = {(e) => setRegUsername(e.target.value)}
required />
<label htmlFor="Password">Password</label>
<input
type="password"
placeholder="Password"
value={regPwd}
onChange = {(e) => setRegPwd(e.target.value)}
required />
<button type="submit" className="btn">
Register
</button>
</form>
);
There are many approaches involved to give to you in a single response, so I recommend you take a look in some tutorials around web, even courses in Udemy, Hotmart, Alura, about React + Spring for CRUD and authentication.
I let to you here this lecture.

Using axios for Register form in React. The onSubmit button is not being read. The onChange button is not being read

I am building my first ecommerce website. I am trying to setup a register/login/logout form with react using an axios get call to a my my mongodb database.
I am having trouble setting input values for form submission. I am pretty sure that i dont have the handle change function setup correctly. I think it would be easier to bring in user data and destruction it but i am not not sure on how to implement a spread operator.
const RegisterScreen = () => {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleChange = (e) => {
console.log(name);
setName (e.target.name);
console.log(email);
setEmail(e.target.email);
setPassword(e.target.password)
console.log(password);
}
'''<div>
<h1>Create Account</h1>
<label htmlFor="name">Name</label>
<input
type="text"
id="name"
value={name}
placeholder="Enter name"
required
onChange={handleChange}
></input>
</div>
The 'onChange' references a single input (e.target is your input). Your input has a nameand a value. You don't have email inside your input, for example.
You must get the value of your input, not email (doesn't exists).
So, a working example will be like this:
const RegisterScreen = () => {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleChange = (e) => {
if (e.target.name === "name") {
setName (e.target.value);
} else if (e.target.name === "email") {
setEmail(e.target.value);
} else
setPassword(e.target.value)
}
}
Or, much better:
const RegisterScreen = () => {
const [data, setData] = useState({});
const handleChange = (e) => {
const newData = {...data}
newData[e.target.name] = e.target.value
setData(newData)
}
}
A working component will be:
import React, { useState } from 'react'
const RegisterScreen = () => {
const [data, setData] = useState({});
const handleChange = (e) => {
const newData = {...data}
newData[e.target.name] = e.target.value
setData(newData)
}
return (
<div>
<h1>Create Account</h1>
<label htmlFor="name">Name</label>
<input
type="text"
name="name"
value={data.name}
placeholder="Enter name"
required
onChange={handleChange}
></input>
<input
type="password"
name='password'
value={data.password}
placeholder="Enter password"
required
onChange={handleChange}
></input>
<input
type="email"
name='email'
value={data.email}
placeholder="Enter email"
required
onChange={handleChange}
></input>
<div>
<ul>
<li>
name: {data.name}
</li>
<li>
password: {data.password}
</li>
<li>
email: {data.email}
</li>
</ul>
</div>
</div>
)
}
export default RegisterScreen
Fully working app on https://github.com/afoone/stackoverflow_answer_-70325367

my state is not getting value into it REACT

I added two handlers to my code. First, mail is entered and handleStart is started, then the user name and password are obtained from the user, and then when the button is pressed, handleFinish is activated and information assignments are made. setEmail state works but password and name states do not
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [name, setName] = useState("");
const history = useHistory();
const url = "http://localhost:3002/register";
const emailRef = useRef();
const passwordRef = useRef();
const usernameRef = useRef();
const handleStart = () => {
setEmail(emailRef.current.value);
}
const handleFinish = async (e) => {
e.preventDefault();
console.log("ref data", passwordRef.current.value,usernameRef.current.value)
//it works and shows values
setPassword(passwordRef.current.value);
setName(usernameRef.current.value);
console.log("state data", email, password, name)
//status values are empty except for email
try {
await axios.post(url, { email, name, password });
history.push("/");
} catch (err) { }
}
and my return (HTML) codes:
{!email ? (
<div className="input">
<input type="email" placeholder="email address" ref={emailRef} />
<button className="registerButton" onClick={handleStart}>
Get Started
</button>
</div>
) : (
<form className="input">
<input type="username" placeholder="username" ref={usernameRef} />
<input type="password" placeholder="password" ref={passwordRef} />
<button className="registerButton" onClick={handleFinish}>
Start
</button>
</form>
)}
It's better to use useState to store and get values and control element rather then using ref.
Here is the code using state, that may help you:
const App = () => {
const history = useHistory();
const url = "http://localhost:3002/register";
const [step, setStep] = useState(0)
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")
const [username, setUsername] = useState("")
const handleStart = () => {
setStep(1)
}
const handleFinish = async (e) => {
e.preventDefault();
console.log("data: ", email, password, username)
try {
await axios.post(url, { email, name, password });
history.push("/");
} catch (err) { }
}
return (
step === 0 ? (
<div className="input">
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="email address"
/>
<button className="registerButton" onClick={handleStart}>
Get Started
</button>
</div>
) : (
<form className="input">
<input
type="username"
placeholder="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<input
type="password"
placeholder="password"
value={password}
onChange={() => setPassword(e.target.value)}
/>
<button className="registerButton" onClick={handleFinish}>
Start
</button>
</form>
)
)
}
This is very well known problem, explained thousands time here,
that state changes are internally asynchronous means we wont get updated state on next line immediately, it takes time to complete execution of setPassword and setName, so next line after set state, console.log would be old values
console.log(passwordRef.current.value)
console.log(usernameRef.current.value)
this must have values, and logged on console but not password and name
this below behavior is correct, known and no issues here,
console.log("state data", email, password, name)
//status values are empty except for email
better would be, this below hack works always for me,
await axios.post(url, { email, usernameRef.current.value, passwordRef.current.value });
If you wish to do some activity based on value change for email, password, name using useEffect could be a better option. You can call API or perform any activity as an effect of those values change. Please find following code -
useEffect(() => {
await axios.post(url, { email, name, password });
history.push("/");
return () => {
// handle cancelling or other clean up
}
}, [email, password, name]);

Pass multiple variable with POST method in React app

I'm trying to post multiple variables to my Postgres database using a form with React.
This is my current script:
const InputAddress = () => {
const [name, setName] = useState("");
const [problem, setProblem] = useState("");
const [date, setDate] = useState("");
const onSubmitForm = async (e) => {
e.preventDefault();
try {
const body = {
name,
problem,
date,
};
console.log(params);
const response = await fetch("http://localhost:5000/logements", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
console.log(response);
window.location = "/";
} catch (error) {
console.log(error.message);
}
};
return (
<Fragment>
<h1 className="text-center mt-5">Add your address</h1>
<form className="d-flex mt-5" onSubmit={onSubmitForm}>
<label>Name</label>
<input
type="text"
className="form-control"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<label>Comment</label>
<input
type="text"
className="form-control"
value={problem}
onChange={(e) => setProblem(e.target.value)}
/>
<label>Date</label>
<input
type="text"
className="form-control"
value={date}
onChange={(e) => setDate(e.target.value)}
/>
<button className="btn btn-success">Submit</button>
</form>
</Fragment>
);
};
My problem seems to be with the fetch method.
When I submit the form, I get this error message in the console :
bind message supplies 1 parameters, but prepared statement "" requires 3
Is there a simple fix to this problem?

Resources