Why can't I type anything into my form inputs - javascript

I have a ReactJS app. I am trying to implement form validation by the accepted answer here as my example. I had to adapt it some because I am using a Function and not a Component (i.e. I don't have a constructor).
Here is the whole function:
import React, { useState } from "react";
import Config from 'config';
import PropTypes from "prop-types";
import "./Login.css";
export default function ChangePassword({ setToken }) {
const [fields, setFields] = useState({});
const [errors, setErrors] = useState({});
const tokenString = sessionStorage.getItem("token");
const token = JSON.parse(tokenString);
let headers = new Headers({
"Accept": "application/json",
"Content-Type": "application/json",
'Authorization': 'Bearer ' + token.token
});
async function changePassword(password) {
return fetch(Config.apiUrl + "/api/Users/ChangePassword", {
method: "POST",
headers: headers,
body: password
})
.then((response) => {
return response.json();
});
}
function handleValidation() {
let formErrors = {};
let formIsValid = true;
//Password
if (!fields["password"]) {
formIsValid = false;
formErrors["password"] = "Cannot be empty";
}
if (typeof fields["password"] !== "undefined") {
if (!fields["password"].match(/^[a-zA-Z0-9!##$%^&?]+$/)) {
formIsValid = false;
formErrors["password"] = "Only accepted";
}
}
//Confirm Password
if (!fields["confirmPassword"]) {
formIsValid = false;
formErrors["confirmPassword"] = "Cannot be empty";
}
if (typeof fields["confirmPassword"] !== "undefined") {
if (!fields["confirmPassword"].match(/^[a-zA-Z0-9!##$%^&?]+$/)) {
formIsValid = false;
formErrors["confirmPassword"] = "Only accepted";
}
}
if (fields["confirmPassword"] != fields["password"]) {
formIsValid = false;
formErrors["confirmPassword"] = "Does not match Password";
}
setErrors({ formErrors });
return formIsValid;
}
const handleSubmit = async e => {
e.preventDefault();
if (handleValidation()) {
const myToken = await changePassword(fields["password"]);
setToken(myToken);
} else {
alert("Form has errors.")
}
}
function handleChange(field, e) {
let myFields = fields;
myFields[field] = e.target.value;
setFields({ myFields });
}
return (
<div className="login wrapper fadeInDown">
<div className="login formContent ">
<h1 className="login centered">Change Password</h1>
<form onSubmit={handleSubmit}>
<div className="centered">
<span style={{ color: "red" }}>{errors["password"]}</span>
<input type="password" value={fields["password"] || ""} onChange={e => handleChange.bind(this, "password")} id="login" className="login fadeIn second" placeholder="Password" />
</div>
<div className="centered">
<span style={{ color: "red" }}>{errors["confirmPassword"]}</span>
<input type="password" value={fields["confirmPassword"] || ""} onChange={e => handleChange.bind(this, "confirmPassword")} id="login" className="login fadeIn third" placeholder="Confirm Password" />
</div>
<div className="centered">
<input type="submit" className="login fadeIn fourth" value="Submit" />
</div>
</form>
</div>
</div>
)
}
ChangePassword.propTypes = {
setToken: PropTypes.func.isRequired
}
The function loads, but I cannot type anything in Password or Confirm Password. For the life of me I can't figure out why. I am hoping a kind SO user will point out my error(s).
UPDATE
Just to be complete... Based on the comment by #evolutionxbox I changed my function changePassword to:
async function changePassword(password) {
const response = await fetch(Config.apiUrl + "/api/Users/ChangePassword", {
method: "POST",
headers: headers,
body: JSON.stringify(password)
})
const json = await response.json();
console.log(json);
return json;
}

As other commenters mentioned, you don't need to .bind in a non-class context.
Change your onChange event handlers from
onChange={e => handleChange.bind(this, "password")}
Add a name attribute to your input elements:
<input name="password" ... />
<input name="confirmPassword" ... />
to
onChange={handleChange}
Then you can update your handleChange function to the following:
function handleChange(e) {
setFields({
...fields,
[e.target.name]: e.target.value
});
}
The above setState has the added benefit of not mutating your existing state object

function handleChange(field, e) {
let myFields = fields;
myFields[field] = e.target.value;
setFields({ myFields });
}
It is a mistake that most new people in react make. UseState is immutable and when you are saying
let myFields = fields;
You are copying a reference to your fields useState. Try destructuring, that will copy the value not reference
let myFields = [...fields];
But my advice would be to create 2 useStates one for password, another for confirmPassword, it will make your code clearer and wont mess up the states. Then change your input element in jsx from that
<input type="password" value={fields["password"] || ""} onChange={e => handleChange.bind(this, "password")} id="login" className="login fadeIn second" placeholder="Password" />
to that
<input type="password" value={fields["password"] || ""} onChange={e => setPassword(e.target.value)} id="login" className="login fadeIn second" placeholder="Password" />

Related

Validating form inputs with React

I am trying to check that the required fields are not empty and making sure that the input type is correct.
const CreateSensor = () => {
const [deveui, setDeveui] = useState('');
const [location, setLocation] = useState('');
const [levelid, setLevel] = useState('');
const submitValue = () => {
let data = {deveui,location,levelid};
//POST method
fetch("api")
ClearFields();
}
function ClearFields(){
document.getElementById("dev").value = "";
document.getElementById("location").value = "";
document.getElementById("level").value = "";
}
return(
<>
<hr/>
<input type="text" id="dev" placeholder="deveui" onChange={e => setDeveui(e.target.value)} />
<input type="text" id="location"placeholder="Location" onChange={e => setLocation(e.target.value)} />
<input type="text" id="level" placeholder="Levelid" onChange={e => setLevel(e.target.value)} />
<button onClick={submitValue}>Submit</button>
</>
)
}
the submit button will check whether deveui is not empty and the levelid is set to an integer.
I have tried changing the input type for levelid to numbers but there is arrows on it which I feel is unnecessary.
I strongly recommend using a React form library. Here's an example with react-hook-form
import { useForm } from "react-hook-form";
const CreateSensor = () => {
const {
register,
handleSubmit,
watch,
reset,
formState: { errors },
} = useForm({ defaultValues: { deveui: "", location: "", levelid: "" } });
const submitValue = ({deveui, location, levelid}) => {
// exclude 'deveui' from fetch payload
const payload = { location, levelid }
// POST data to api, for example
fetch("https://myapi.com", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
// reset form state
}).then((response) => reset());
};
return (
<>
<hr />
<form onSubmit={handleSubmit(submitValue)}>
<input
{...register("deveui", { required: true })}
type="text"
id="dev"
placeholder="deveui"
/>
<input
{...register("location", { required: true })}
type="text"
id="location"
placeholder="Location"
/>
<input
{...register("levelid", { required: true })}
type="text"
id="level"
placeholder="Levelid"
/>
<button type="submit">Submit</button>
</form>
</>
);
}

onSubmit React js problems

I have a problem with React JS.
I have a form where the user has to pick some options and then write a number, when the user press a button named "Consultar" or press "Enter" (Intro) it suposed to send the form and show a table with the necessary information.
However, when the user press "Enter" the form information is not submitted, the only way is by pressing the button named "Consultar". I have tried using onKeyPress but it did not work.
Could it be some react bug causing the problem and not my code? If it is not something in my code, what I need is that the user can press "Enter" and that it does the same function of the "Consultar" button.
Please help, I am very new in this world of React JS. Here is the code:
const DataForm = ({
update,
setIsLoaded,
setError,
}) => {
const formatChars = { C: '[1-9]', L: '[0-9]', Z: '[0-9]?' };
const [tipoCedula, setTipoCedula] = useState('1');
const [tipoBusqueda, setTipoBusqueda] = useState('1');
const [numCedula, setNumCedula] = useState('');
const [emailAddress, setEmailAddress] = useState('');
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
tipoCedula,
tipoBusqueda,
numCedula,
emailAddress,
});
const getNumCedulaMask = (pTipoCedula) => {
if (pTipoCedula === '2') return 'C-LLL-LLLLLL';
if (pTipoCedula === '3') return 'CLLLLLLLLLLZ';
if (pTipoCedula === '4') return 'CLLLLLLLLL';
return 'C-LLLL-LLLL';
};
const getRegExFromMask = (pMask, pFormatChars) => {
let returnValue = pMask;
Object.keys(pFormatChars).map((item) => {
if (typeof returnValue.replaceAll === 'function') {
returnValue = returnValue.replaceAll(item, pFormatChars[item]);
}
return returnValue;
});
return new RegExp(`^${returnValue}$`);
};
const numCedulaMask = getNumCedulaMask(tipoCedula);
const numCedulaRegEx = getRegExFromMask(numCedulaMask, formatChars);
const emailRegEx = '^[_a-z0-9-]+(.[_a-z0-9-]+)*#[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4})$';
const isValidNumCedula = (inputValue) => {
const replace = inputValue.replace('_', '');
if (replace.match(numCedulaRegEx)) {
return true;
}
return 'El formato no es válido';
};
const isValidEmail = (inputValue) => {
if (inputValue.match(emailRegEx)) {
return true;
}
return 'El formato no es válido';
};
const onSubmit = async (data) => {
let searchParameter = '';
if (data.tipoBusqueda === '1') {
searchParameter = data.numCedula;
} else {
searchParameter = data.emailAddress;
}
const { ssoBaseUrl } = some restricted information
const apiCall = some restricted information
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
};
setIsLoaded(true);
try {
const result = await fetch(apiCall, requestOptions);
const datos = await result.json();
setIsLoaded(false);
update('reminderResult', datos);
} catch (e) {
setError(true);
}
};
return (
<div>
<form onSubmit={handleSubmit(onSubmit)} id='formulario' data-testid='formulario-busqueda'>
<div className='form-group group_TIPO_BUSQUEDA'>
<label className='label'>Buscar por</label>
<div>
<select data-testid="search-type"
className='form-control select TIPO_BUSQUEDA'
{...register('tipoBusqueda')}
defaultValue={tipoBusqueda}
onChange={(e) => (setTipoBusqueda(e.target.value))}
>
<option value='1'>Tipo de cedula</option>
<option value='2'>Email</option>
</select></div>
</div>
{tipoBusqueda === '1' && <div className='form-group group_TIPO_CEDULA'>
<label htmlFor='tipoCedula' className='label'>Tipo de cédula</label>
<div>
<select data-testid="cedula-tipo-id"
className='form-control select TIPO_CEDULA'
{...register('tipoCedula')}
defaultValue={tipoCedula}
onChange={(e) => (setTipoCedula(e.target.value))}
>
<option value='1'>Cédula Persona Física</option>
<option value='2'>Cédula Persona Jurídica</option>
<option value='4'>Número Identificación Tributario Especial (NITE)</option>
<option value='3'>Documento Identificación Migratorio Extranjeros</option>
</select>
{errors.tipoCedula && <p className='error-message'>{errors.tipoCedula.message}</p>}
</div>
</div>
}
{tipoBusqueda === '1' && <div className='form-group group_NUM_CEDULA'>
<label htmlFor='numCedula' className='label'>Cédula</label>
<div>
<InputMask data-testid="num-cedula"
className='form-control NUM_CEDULA input'
{...register('numCedula', {
required: {
value: true,
message: 'Este campo es requerido',
},
validate: {
validValue: isValidNumCedula,
},
})}
formatChars={formatChars}
onChange={(e) => (setNumCedula(e.target.value))}
value={numCedula}
mask={numCedulaMask}
/>
{errors.numCedula && <p className='error-message' role="alert">Formato cédula incorrecto</p>}
</div>
</div>}
{tipoBusqueda === '2' && <div className='form-group'>
<label htmlFor='emailAddress' className='label'>Dirección de correo electrónico</label>
<div>
<input type="text"
data-testid="emailAddress"
className="form-control"
value={emailAddress}
{...register('emailAddress', {
required: 'Este campo es requerido',
validate: {
validValue: isValidEmail,
},
})}
onChange={(e) => (setEmailAddress(e.target.value))}
/>
{errors.emailAddress && <p className='error-message' role="alert">{errors.emailAddress.message}</p>}
</div>
</div>}
<div className='form-group'>
<button className='btn-submit float-right' type="submit" data-testid="button-ask">CONSULTAR</button>
</div>
</form>
</div>
);
};
DataForm.propTypes = {
update: PropTypes.func.isRequired,
setIsLoaded: PropTypes.func.isRequired,
setError: PropTypes.func.isRequired,
};
export default DataForm;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
I did not try your code, but i saw your code and i find here something. You have to write to arrow function in onSubmit.
<form onSubmit={() => handleSubmit(onSubmit)} id='formulario' data-testid='formulario-busqueda'>
If your page getting refresh on submit, then you have to write event.preventDefault() onSubmit.
<form onSubmit={(event) => {
event.preventDefault();
handleSubmit(onSubmit);
} id='formulario' data-testid='formulario-busqueda'>
Here is a code example how to submit forms with enter key:
import React, { useState } from 'react';
export default function App() {
const [name, setName] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
console.log('form submited');
};
return (
<div>
<form onSubmit={handleSubmit} >
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</form>
</div>
);
}
....
You don't have a handleSubmit function, what you have is an onSubmit function. Therefore, in your onSubmit event listener, you are trying to call a non-existent function
<form onSubmit={handleSubmit(onSubmit)}...
This is how you should call the onSubmit function
<form onSubmit={onSubmit}...

Password States are reacting one character late

Im checking to see if the register forms passwords match, and when they do, something changes. but its happening on 1 "onChange" too late. Ex. User enters "DOG" as the password. when the retype it in the 2nd input, "DOG" doesnt work. but it does if they enter another character or delete one character (Ex. "DOGX" or deleting "G" so its "DO")
import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import "./register.css";
function RegisterBoard() {
const history = useHistory();
const [register, changeRegister] = useState({
password: false,
repeatPassword: false,
});
const [info, changeInfo] = useState({
password: "",
repeatPassword: "",
});
const changeValue = (e) => {
const { name, value } = e.target;
changeInfo((prev) => {
return {
...prev,
[name]: value,
};
});
};
const input = (e) => {
const target = e.target.dataset.name;
if (target != "repeatPassword") {
changeRegister({
...register,
[target]: true,
});
} else {
if (info.password != info.repeatPassword) {
changeRegister({
...register,
repeatPassword: false,
});
} else {
changeRegister({
...register,
repeatPassword: true,
});
}
}
};
return (
<div className="registration-form">
<form>
<div>
<input
name="password"
data-name="password"
onChange={(e) => {
changeValue(e);
input(e);
}}
className="password"
type="password"
placeholder="ENTER YOUR PASSWORD HERE"
/>
<div className="animated-button">
</div>
</div>
<div>
<input
id="pwd"
name="repeatPassword"
data-name="repeatPassword"
onChange={(e) => {
changeValue(e);
input(e);
}}
className="repeat-password"
type="password"
placeholder="REPEAT YOUR PASSWORD HERE"
/>
</div>
</div>
</form>
</div>
);
}
export default RegisterBoard;
I guess this is because you are calling both 'changeValue' and 'input' functions within the inputs onChange attribute. Since they are firing at the same time, 'input' is not using the most recent value for 'info', because 'changeValue' hasn't set the new state yet.
Either call the input function within a useEffect hook which is dependent on changes to 'info's' state, or use e.target.value instead of info's state within the 'input' function to compare info.password != info.repeatPassword
EDIT: here is the useEffect way, it simplifies it and you can remove your input function completely: https://codesandbox.io/s/jolly-khorana-8s63b?file=/src/App.js
import React, { useState, useEffect } from "react";
import "./styles.css";
function RegisterBoard() {
const [register, changeRegister] = useState({
password: false,
repeatPassword: false
});
const [info, changeInfo] = useState({
password: "",
repeatPassword: ""
});
const changeValue = (e) => {
const { name, value } = e.target;
changeInfo((prev) => {
return {
...prev,
[name]: value
};
});
};
useEffect(() => {
let password = false;
let repeatPassword = false;
if (info.password !== "") {
password = true;
if (info.password === info.repeatPassword) {
repeatPassword = true;
}
}
changeRegister({ password, repeatPassword });
}, [info]);
return (
<div className="registration-form">
<form>
<div>
<input
name="password"
data-name="password"
onChange={changeValue}
className="password"
type="password"
placeholder="ENTER YOUR PASSWORD HERE"
/>
<div className="animated-button"></div>
</div>
<div>
<input
id="pwd"
name="repeatPassword"
data-name="repeatPassword"
onChange={changeValue}
className="repeat-password"
type="password"
placeholder="REPEAT YOUR PASSWORD HERE"
/>
</div>
</form>
<div>{info.password}</div>
<div>{info.repeatPassword}</div>
<div>{register.repeatPassword ? "match" : "don't match"}</div>
</div>
);
}
export default function App() {
return (
<div className="App">
<RegisterBoard />
</div>
);
}
You're definitely going to want to implement a useEffect here to update the UI every time the password & repeatPassword state changes, to ensure that after the last character is typed that you get the full password. Inside the useEffect is where you'll write your conditional logic. What I provided is just a good example...
import React, { useState, useEffect } from "react";
import { useHistory } from "react-router-dom";
import "./register.css";
function RegisterBoard() {
const history = useHistory();
const [password, setPassword] = useState('')
const [repeatPassword, setRepeatPassword] = useState('')
//const [register, changeRegister] = useState(false);
const changeValue = (e) => {
const { name, value } = e.target.value;
const input = (e) => {
const target = e.target.dataset.name;
if (target != "repeatPassword") {
changeRegister({
...register,
[target]: true,
});
} else {
if (info.password != info.repeatPassword) {
changeRegister({
...register,
repeatPassword: false,
});
} else {
changeRegister({
...register,
repeatPassword: true,
});
}
}
};
useEffect(() => {
if((password !== "" && repeatPassword !== "") && (password !==
repeatPassword)){
console.log("PASSWORDS DO NOT MATCH!!!")
}
console.log(password, repeatPassword)
}, [password, repeatPassword])
return (
<div className="registration-form">
<form>
<div>
<input
name="password"
data-name="password"
onChange={(e) => changeValue(e)}
className="password"
type="password"
placeholder="ENTER YOUR PASSWORD HERE"
/>
<div className="animated-button">
</div>
</div>
<div>
<input
id="pwd"
name="repeatPassword"
data-name="repeatPassword"
onChange={(e) => changeValue(e)}
className="repeat-password"
type="password"
placeholder="REPEAT YOUR PASSWORD HERE"
/>
</div>
</div>
</form>
</div>
);
}
export default RegisterBoard;

REACT Cannot read property 'value' of null at onKeyPress

I have a react component called EmailSubscribe that takes the value of a text input box and sends it through a fetch request. I have saved two elements into variables, emailInput and emailContainer, however, I am getting the following error message:
Uncaught TypeError: Cannot read property 'value' of null
at onKeyPress
I have not had this issue with other components and my code works if I replace emailInput and emailContainer with document.querySelector('XXXX') each time I need it, but this is not a clean way of doing it. Any idea why I'm getting this error message?
App.js:
import ResultsPage from "./pages/ResultsPage/results";
import Header from "./components/Header";
import EmailSubscribe from "./components/EmailSubscribe";
function App() {
return (
<div className="App">
<Header />
<ResultsPage />
<EmailSubscribe />
</div>
);
}
export default App;
EmailSubscribe.jsx:
function EmailSubscribe() {
const emailContainer = document.querySelector(".email-container");
const emailInput = document.querySelector(".email-input");
const isValidEmail = (email) => {
var validEmailRegex = /\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*/;
return validEmailRegex.test(email);
};
const resetEmailSubscribe = (newValue, newPlaceholder, isErrorMessage) => {
emailInput.value = newValue;
emailInput.placeholder = newPlaceholder;
if (isErrorMessage) {
emailInput.classList.add("placeholderColorOrange");
} else {
emailInput.classList.remove("placeholderColorOrange");
}
};
const emailSubscribePOST = (email) => {
if (email.trim() == "") {
resetEmailSubscribe("", "Please enter your email address", true);
} else if (!isValidEmail(email)) {
resetEmailSubscribe("", "Invalid email address", true);
} else {
fetch("http://127.0.0.1:5000/subscribe", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({ email: email }),
})
.then((res) => res.json())
.then((res) => {
if (res.message == "Email sent successfully") {
emailContainer.innerHTML =
"<p class='email-thankyou'>Thank you for subscribing!</p>";
} else if (res.message == "Email already registered") {
resetEmailSubscribe("", res.message, true);
}
});
}
};
return (
<div class="email-container">
<input
type="text"
className="email-input"
placeholder="Register or log in"
onKeyPress={(e) =>
e.key === "Enter" && emailSubscribePOST(emailInput.value)
}
/>
<button
type="button"
className="email-submit-btn btn"
onClick={() => {
emailSubscribePOST(emailInput.value);
}}
>
Submit
</button>
</div>
);
}
export default EmailSubscribe;
In general, don't access items with document.get... in react. In React you have state for the things you are doing.
function EmailSubscribe() {
const [input, setInput] = useState("");
const [placeholder, setPlaceholder] = useState("Register or log in");
const [hasSubscribed, setHasSubscribed] = useState(false);
const [hasErrorMessage, setHasErrorMessage] = useState(false);
const isValidEmail = (email) => {
var validEmailRegex = /\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*/;
return validEmailRegex.test(email);
};
const resetEmailSubscribe = (newValue, newPlaceholder, hasErrorMessage) => {
setInput(newValue);
setPlaceholder(newPlaceholder);
setHasErrorMessage(hasErrorMessage);
};
const emailSubscribePOST = (email) => {
if (email.trim() == "") {
resetEmailSubscribe("", "Please enter your email address", true);
} else if (!isValidEmail(email)) {
resetEmailSubscribe("", "Invalid email address", true);
} else {
fetch("http://127.0.0.1:5000/subscribe", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({ email: email }),
})
.then((res) => res.json())
.then((res) => {
if (res.message == "Email sent successfully") {
setHasSubscribed(true)
} else if (res.message == "Email already registered") {
resetEmailSubscribe("", res.message, true);
}
});
}
};
return (
<div class="email-container">
{hasSubscribed ?
<p class='email-thankyou'>Thank you for subscribing!</p>
:
<input
type="text"
className={hasErrorMessage ? "placeholderColorOrange" : ""}
placeholder={emailInputPlaceholder}
onChange={e => setInput(e.target.value)}
value={input}
onKeyPress={(e) =>
e.key === "Enter" && emailSubscribePOST(input)
}
/>
<button
type="button"
className="email-submit-btn btn"
onClick={() => {
emailSubscribePOST(input);
}}
>
Submit
</button>
}
</div>
);
}
export default EmailSubscribe;
The main issue here is you do not have a value attribute in your input text box.Try adding the 'value' attribute to your input text and set the state with onChange like below:
<input
type="text"
className="email-input"
placeholder="Register or log in"
value={emailInput}
onChange={(e)=>setEmailInput(e.value)
onKeyPress={(e) =>
e.key === "Enter" && emailSubscribePOST(emailInput)
}
/>
<button
type="button"
className="email-submit-btn btn"
onClick={() => {
emailSubscribePOST(emailInput);
}}
>
It should work.

Login page verification in reactjs

I want to translate an angularjs login page to reactjs. I did the code but I want to know if it's the right way to do it and if it's correct till what I have done. Also I want to add the dashboard page which can be accessed only authentication and user will be redirected to dashboard after login.
$scope.login=function(){
$scope.newuser={
'password':$scope.signinpassword,
'email':$scope.emailid
}
return $http.post('/api/authenticate',$scope.newuser).then(function(response,status){
if(response.data=='redirect'){
$window.location.href="/dashboard";
}else if(response.data=='verifyemail'){
angular.element(document.querySelector('#verifyemailbtn')).click();
}else if(response.data=='Invalid Password'){
window.alert("Incorrect Password");
$scope.error='Failed to authenticate'
}
});
}
my reactjs code that I translated so far
class Login extends Component {
constructor(props){
super(props);
this.state={
emailid:'',
password:''
}
}
performLogin = async (event) => {
var body={
"emailid":"this.state.emailid",
"password":"this.state.password"
}
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: body
};
const url = "api/login";
try {
const response = await fetch(url, options);
const result = await response.json();
console.log(`login successful`);
} catch (error) {
console.error("login credentials wrong");
}
};
render() {
return (
<div>
<input type="text"
placeholder="emailid"
onChange = {(event,newValue) => this.setState({emailid:newValue})}
/>
<br/>
<input
type="password"
placeholder="Enter your Password"
onChange = {(event,newValue) => this.setState({password:newValue})}
/>
<br/>
<button type="submit" onClick={(event) => this.performLogin(event)}/>
</div>
);
}
}
export default Login;
your code approaching is ok but have some syntax issues.
1- your need to bind "this" for methods in constructor
2- remove double quotation in performLogin for this.state.emailid
3- you don't need many functions for each input you can just handle all input feilds just with one function like so.
i refactor your code :-)
class Login extends Component {
constructor(props){
super(props);
this.performLogin = this.performLogin.bind(this)
this.handleChange = this.handleChange.bind(this)
this.state={
emailid:'',
password:''
}
}
performLogin = async (event) => {
const { enteredText } = this.state;
var body={
"emailid":this.state.emailid,
"password":this.state.password
}
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: body
};
const url = "api/login";
try {
const response = await fetch(url, options);
const result = await response.json();
$window.location.href="/dashboard";
} catch (error) {
console.error("login credentials wrong");
}
};
handleChange(e) {
this.setState({[e.target.name]:e.target.value})
}
render() {
return (
<div>
<input type="text"
placeholder="emailid"
onChange = {handleChange}
/>
<br/>
<input
type="password"
placeholder="Enter your Password"
onChange = {handleChange}
/>
<br/>
<button type="submit" onClick={this.performLogin}/>
</div>
);
}
}
export default Login;
for redirecting you can use lib like React-Router or just replace console.log(login successful) with $window.location.href="/dashboard"

Categories