The input values ​are empty after the refresh - how to resolve that? - javascript

I have an api that is of the GET type and I receive the data below code and store it in fetchPlants
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const fetchPlants = async () => {
try {
const { data } = await axios.get(
"URL",
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
setAllPlants(data.plantsList);
} catch (error) {
console.error(error.message);
}
};
fetchPlants();
}, []);
And I have an api of POST type that I send with the below code and I put loading inside it
When it is sent successfully, the page is directed and I have no problem, but I get an error when setLoading is set to false and refresh page, the input values ​​are empty and the user has to enter the input values ​​again.
const sendDisease = async (e) => {
e.preventDefault();
setIsLoading(true);
try {
const api = "URL";
const { data } = await axios.post(api, formData, {
headers: {
headers: { "Content-Type": "multipart/form-data" },
Authorization: `Bearer ${token}`,
},
});
if (data) {
setIsLoading(false);
navigate("/dashboard/diseases/");
toast.success(data.success, { autoClose: 15000 });
}
} catch (e) {
setIsLoading(false);
console.log(e);
toast.error(e.response.data.error, { autoClose: 15000 });
console.log(e.response.data.error);
}
};
this is my form:
<div className="form-row mt-4">
<div className="col-md-6 mb-3">
<label className="font-weight-bold" for="">
Unique Name
</label>
<input
type="text"
className="form-control"
name="unique_name"
placeholder="Unique Name"
required
onChange={(e) => setUniqueName(e.target.value)}
/>
</div>
<div className="col-md-6 mb-3">
<label className="font-weight-bold" for="">
Title
</label>
<input
type="text"
className="form-control"
name="title"
placeholder="Title"
onChange={(e) => setTitle(e.target.value)}
required
/>
</div>
</div>
<button
type="button"
className="btn btn-primary mt-4"
onClick={sendDisease}
>
Submit
</button>
</form>
I want the values ​​not to be clear, but when it goes false, the input values ​​are empty. how to resolve that?

Related

React sending empty form values to backend

I can't figure out why my form is populating my backend struct with empty strings. I can only get it to send the data correctly if I replace my onSubmit={handleSubmit} with method="POST" action="/createLink"
But even then it seems to send two form inputs.. one with empty values and one populated correctly. Backend is in Go.
const Home = () => {
//create state variables
const [media, setMedia] = React.useState([])
const [url, setURL] = React.useState(null)
const [headline, setHeadline] = React.useState(null)
const [description, setDescription] = React.useState(null)
const [type, setType] = React.useState(null)
const [duration, setDuration] = React.useState(null)
const [address, setAddress] = React.useState(null)
//HOOKS
//get media already submitted today to display on the front end
useEffect(() => {
fetch("/getMedia", {
method: "GET",
headers: {
"Content-Type" : "application/json",
},
})
.then((res) => res.json())
.then((data) => {
console.log(data)
setMedia(...media, data);
});
}, []);
//direct user back to home page
let navigate = useNavigate()
const handleHome = () => {
navigate("/")
}
//submit media
const handleSubmit = (e) => {
e.preventDefault()
fetch("/createLink", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
url: url,
headline: headline,
description: description,
type: type,
duration: duration,
address: address,
}),
})
console.log(address, "why")
handleHome()
}
//method="POST" action="/createLink"
return (
<>
<Div>
<H1>Submit External Media</H1>
<form onSubmit={handleSubmit} >
<Field>
<label htmlFor="url">URL Submission:</label>
<Input type="text" id="url" name="url" required onChange={(e) => {
setURL(e.target.value)
}}></Input>
</Field>
<Field>
<label htmlFor="headline">Headline:</label>
<Input type="text" id="headline" name="headline" required onChange={(e) => {
setHeadline(e.target.value)
}}></Input>
</Field>
<Field>
<label htmlFor="description">Description:</label>
<Input type="text" id="description" name="description" required onChange={(e) => {
setDescription(e.target.value)
}}></Input>
</Field>
<Field>
<label htmlFor="type">Type of Media:</label>
<select id="type" name="type" onChange={(e) => {
setType(e.target.value)
}}>
<option value="article" >Article</option>
<option value="tweet" >Tweet</option>
<option value="yt-video" >YouTube Video</option>
</select>
</Field>
<Field>
<label htmlFor="duration">Duration:</label>
<select id="duration" name="duration" onChange={(e) => {
setDuration(e.target.value)
}}>
<option value="15">15 Hours</option>
<option value="48" >48 Hours</option>
<option value="two-weeks" >Two Weeks</option>
</select>
</Field>
<Field>
<label htmlFor="location-lng">Street Address:</label>
<Input type="text" id="location-lng" name="location-lng" onChange={(e) => {
setAddress(e.target.value)
console.log(address)
}}></Input>
</Field>
<Button type="submit">SUBMIT</Button>
</form>
<h2>Media Submitted Today:</h2>
{ media.length >= 1 ? (
media.map((mediaItem) => {
const headline = mediaItem.headline
const description = mediaItem.description
const url = mediaItem.url
return <Media headline={headline} description={description} url={url} />
})
) : (
<>
<p>Looks like no external media was submitted yet today!</p>
</>
)}
</Div>
</>
)
}
export default Home;
One reason it might work with method="POST", but it is not working with your javascript function is that the default content type for a form is application/x-www-form-urlencoded.
In handleSubmit it sets the type to application/json, which your backend may not be expecting, and is not decoding properly.
Please consider this:
console.log everything before sending and validate input values are correct
The Input component seems to be Uncontrolled, validate if state if being set correctly
fetch is async and you're re-directing & pushing browser history state the user without waiting for the fetch call to end
Do this for advice 3:
//direct user back to home page
let navigate = useNavigate()
const handleHome = () => {
navigate("/")
}
//submit media
const handleSubmit = (e) => {
e.preventDefault()
fetch("/createLink", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
url: url,
headline: headline,
description: description,
type: type,
duration: duration,
address: address,
}),
}).then(() => handleHome()) // We are sure data was sent
}
Do this for advice 1:
//direct user back to home page
let navigate = useNavigate()
const handleHome = () => {
navigate("/")
}
//submit media
const handleSubmit = (e) => {
e.preventDefault()
const data = {
url,
headline,
description,
type,
duration,
address,
}
console.log({ data }) // Check the dev console
// JS Enhanced Object literals.
// https://www.sitepoint.com/es6-enhanced-object-literals
fetch("/createLink", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
}).then(() => handleHome()) // We are sure data was sent
}

How to put an error message when putting the credentials wrong in a login

I am doing a login, and I need that when I enter the wrong password or the email I get an error message but I do not know how to do it, I am working with the POST method and also in nextjs
this is my code:
function Login({}) {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
useEffect(() => {
if (localStorage.getItem("user-info")) {
}
}, []);
async function login() {
console.warn(email, password);
let item = { email, password };
let result = await fetch(
"https://login-test.repl.co/auth/login",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(item),
}
);
result = await result.json();
localStorage.setItem("user-info", JSON.stringify(result));
}
return (
<div className="bg-white w-full rounded-lg shadow p-2 h-screen flex justify-center items-center relative">
<div className="w-full ">
<input
id="inputEmail"
onChange={(e) => setEmail(e.target.value)}
type="email"
/>
<input
id="inputPassword"
onChange={(e) => setPassword(e.target.value)}
type="password"
/>
<button type="submit" onClick={login}>
Login
</button>
<div className={`${!error ? "hidden" : ""}`}>
INCORRECT PASSWORD OR EMAIL
</div>
</div>
</div>
);
}
export default Login;
when I put the wrong password or the mail they send me this:
Can you check like this
function Login({}) {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState(null);
useEffect(() => {
if (localStorage.getItem("user-info")) {
}
}, []);
async function login() {
setError(false);
console.warn(email, password);
let item = { email, password };
try {
let result = await fetch(
"https://login-test.repl.co/auth/login",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(item),
}
);
result = await result.json();
localStorage.setItem("user-info", JSON.stringify(result));
} catch(error) {
setError(true);
}
}
return (
<div className="bg-white w-full rounded-lg shadow p-2 h-screen flex justify-center items-center relative">
<div className="w-full ">
<input
id="inputEmail"
onChange={(e) => setEmail(e.target.value)}
type="email"
/>
<input
id="inputPassword"
onChange={(e) => setPassword(e.target.value)}
type="password"
/>
<button type="submit" onClick={login}>
Login
</button>
<div className={`${!error ? "hidden" : ""}`}>
INCORRECT PASSWORD OR EMAIL
</div>
</div>
</div>
);
}
export default Login;
You can achieve this by checking the status code.
If you are getting status of 200 then you can update the state as follows:
if(result.status === 200)
{
setEmail("Email Already Exists");
}
You can get more status codes and you can set the errors as you like.

Why are my login/register buttons still working when empty?

I have created an app with a simple login/register form that will give a user a token and stores it in localStorage. I also have a logout function in place which will remove the token from storage. Everything works as planned however, if I press the form button to login or to register, it will still give access to the dashboard until the page is refreshed.
Login.js
const Login = ({ setAuth }) => {
const [inputs, setInputs] = useState({
email: '',
password: '',
});
const { email, password } = inputs;
//Handle form inputs
const changeHandler = (e) => {
setInputs({
...inputs,
[e.target.name]: e.target.value,
});
};
//Form submit handler
const submitHandler = async (e) => {
e.preventDefault();
try {
const body = { email, password };
const response = await fetch('http://localhost:5000/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
//Retrive token from URL
const parseRes = await response.json();
//Save token in local storage then give user authorization
localStorage.setItem('token', parseRes.token);
setAuth(true);
} catch (err) {
console.error(err.message);
}
};
return (
<Fragment>
<div className='container'>
<h1 className='text-center my-5'>Login</h1>
<form onSubmit={submitHandler}>
<input
type='email'
name='email'
placeholder='Email'
className='form-control my-3'
value={email}
onChange={(e) => changeHandler(e)}
/>
<input
type='password'
name='password'
placeholder='Password'
className='form-control my-3'
value={password}
onChange={(e) => changeHandler(e)}
/>
<button className='btn btn-success w-100'>Login</button>
</form>
<Link to='/register'>Register</Link>
</div>
</Fragment>
);
};
In the console after trying to login with an empty form, I get 2 errors from my server side routes: POST http://localhost:5000/auth/login 401 (Unauthorized) and GET http://localhost:5000/dashboard/ 401 (Unauthorized). These errors are expected and working as they are supposed to.
Is there something wrong with my form or could this be in another area of my code?

Protecting pages in react, without blocking a route

Following issue:
I am trying to create an authentication system in react, which let's a user login, sign up and reset the password. The problem is, I want to let the user go certain routes such as /profile, but display the content if he is logged in. If he is not logged in, I want to simply display the navigation bar and a small login component.
So far I tried something like this: (In order to make it more readable I left out the action-blocks)
const Profile = ({ history }) => {
const [values, setValues] = useState({
username: "",
email: "",
password: ""
});
const [isShowingAuth, setIsShowingAuth] = useState(null);
const { username, email, password } = values;
useEffect(() => {
if (!isLoggedIn()) {
setIsShowingAuth("login");
} else {
loadProfileData();
}
}, []);
const loadProfileData = () => {
const userEmail = isLoggedIn().email;
const token = getCookie("token");
axios({
method: "GET",
url: `${process.env.REACT_APP_BACKEND_URL}/user`,
headers: { Authorization: `Bearer ${token}` },
data: { userEmail }
})
.then(response => {
// Do something
})
.catch(error => {
// Do something
});
};
const handleChange = name => event => {
setValues({ ...values, [name]: event.target.value });
};
const handleUpdateUserSubmit = e => {
e.preventDefault();
const token = getCookie("token");
axios({
method: "PUT",
url: `${process.env.REACT_APP_BACKEND_URL}/user/update`,
headers: { Authorization: `Bearer ${token}` },
data: { username, password, email }
})
.then(response => {
// Do something
})
.catch(error => {
// Do something
}
store.addNotification({
...defaultSettings,
type: "danger",
title: "User update error",
message: error.response.data.errorMsg
});
});
};
const deleteAccount = () => {
const token = getCookie("token");
axios({
method: "DELETE",
url: `${process.env.REACT_APP_BACKEND_URL}/user`,
headers: { Authorization: `Bearer ${token}` }
})
.then(response => {
// Do something
})
.catch(error => {
// Do something
};
const showDeleteConfirmation = () => {
// Do something
};
return (
<Layout isShowingAuth={isShowingAuth}>
{isLoggedIn() && isLoggedIn().role === "member" ? (
<>
<ReactNotifications />
<h1 className='mt-5 pl-3'>Profile</h1>
<form className='form col-md-6 mt-3'>
<div className='form-group'>
<label>Name</label>
<input
type='text'
className='form-control'
value={username}
onChange={handleChange("username")}
/>
</div>
<div className='form-group'>
<label>Email</label>
<input
type='email'
className='form-control'
value={email}
onChange={handleChange("email")}
disabled
/>
</div>
<div className='form-group'>
<label>Password</label>
<input
type='password'
className='form-control'
value={password}
onChange={handleChange("password")}
placeholder='Enter your new password'
autoComplete='on'
/>
</div>
<button type='submit' className='btn btn-outline-primary' onClick={handleUpdateUserSubmit}>
Update User
</button>
<button type='button' className='btn btn-outline-danger ml-3' onClick={showDeleteConfirmation}>
Delete account
</button>
<button type='button' className='btn btn-outline-danger ml-3 mt-2 mt-md-0'>
Want to change your email?
</button>
</form>
{showAlert}
</>
) : null}
</Layout>
);
};
Basically I am checking through the isLoggedIn() method if the user is logged in. If he is, I want to render the content, if not I am returning only the layout. The layout contains the navigation bar.
The problem now is, that once the user logs in while being on the route /profile, the component doesn't remount, which means the useEffect(()=> {},[]) is not called again and my profile data is not loaded.
I already tried to refresh the page once logged in through history.push(history.location.pathname), but this doesn't trigger a remount either.
I'm no wondering how to properly trigger a remount after login, and if the way I am setting my authentication system up is secure or if there are better solutions.
Any help / feedback appreciated thanks :)

How to connect login API in reactjs

I am creating login form for practice. I need to connect online API. I have no idea hot connect login API . I Just connect only fetch data API and not able to connect login API. I have design but not able to connect API .I am working in "react": "^16.12.0". using react hooks
enter code here
import React, { useState } from "react";
import { Wrapper } from "./vehiclesTableStyles";
import { PostData } from "./postData";
function VehiclesTable() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const submitForm = e => {
e.preventDefault();
PostData(username, password).then(result => {
console.log(result);
});
console.log("username", username);
console.log("password", password);
};
return (
<Wrapper>
<div className="search_box">
<form onSubmit={submitForm}>
<input
name="name"
type="text"
placeholder="username"
onChange={e => setUsername(e.target.value)}
/>
<input
name="password"
type="password"
placeholder="search"
onChange={e => setPassword(e.target.value)}
/>
<input type="submit" value="login" />
</form>
</div>
</Wrapper>
);
}
export default VehiclesTable;
export function PostData(userData) {
let BaseUrl = "https://reqres.in//api/login";
console.log("userData", userData);
return new Promise((resolve, reject) => {
fetch(BaseUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
// body: JSON.stringify(userData)
})
.then(response => response.json())
.then(responseJson => {
resolve(responseJson);
})
.catch(error => {
reject(error);
});
});
}
I also have the same problem. check the code below. You are making some mistake in code while calling api. You need to call in React life cycle hooks that is the best way.
enter code here
import React, { useState } from "react";
import { Wrapper } from "./vehiclesTableStyles";
import { PostData } from "./postData";
function VehiclesTable() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const submitForm = e => {
e.preventDefault();
PostData(username, password).then(result => {
console.log(result);
});
console.log("username", username);
console.log("password", password);
};
return (
<Wrapper>
<div className="search_box">
<form onSubmit={submitForm}>
<input
name="name"
type="text"
placeholder="username"
onChange={e => setUsername(e.target.value)}
/>
<input
name="password"
type="password"
placeholder="search"
onChange={e => setPassword(e.target.value)}
/>
<input type="submit" value="login" />
</form>
</div>
</Wrapper>
);
}
export default VehiclesTable;
export function PostData(userData) {
let BaseUrl = "https://reqres.in//api/login";
console.log("userData", userData);
return new Promise((resolve, reject) => {
fetch(BaseUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
// body: JSON.stringify(userData)
})
.then(response => response.json())
.then(responseJson => {
resolve(responseJson);
})
.catch(error => {
reject(error);
});
});
I am creating syntax error 'reqres.in//api/login' correct is 'reqres.in/api/login' and also sending email and password as array. that should I have to send as object. like this{email, password}
fetch(baseUrl,
{
method: "POST",
mode: 'cors', // no-cors, cors, *same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
referrer: 'no-referrer',
headers: {
'Content-Type': 'application/json',
...headers
}
})
use this basic fetch config

Categories