REACT Cannot read property 'value' of null at onKeyPress - javascript

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.

Related

cant reset input in functional component in react js

i have a function component called TextInput and return an input element:
function TextInput({ type = "text", label, name, required = false }) {
const [value, setValue] = useState("");
function handleChange(e) {
setValue(e.target.value);
}
return (
<div className={styles.footerFormInput}>
<input
type={type}
value={value}
onChange={handleChange}
name={name}
required={required}
/>
<label className={value && styles.filled} htmlFor={name}>
{label}
</label>
</div>
);
}
i am trying to reset the form, but the value doesnt reset on Customized TextInput but yes on normal/original input element.
this is my page code:
const form = useRef();
const sendEmail = (e) => {
e.preventDefault();
const inputData = e.target.elements;
if (inputData.from_email) {
if (validator.isEmail(inputData.from_email.value)) {
console.log("valid email");
} else {
// alert("Enter valid Email!");
//email error..
return;
}
}
if (inputData.full_name) {
if (
validator.isAlpha(inputData.full_name.value, ["he"], {
ignore: " ",
}) ||
validator.isAlpha(inputData.full_name.value, ["en-US"], {
ignore: " ",
})
) {
console.log("valid name");
} else {
//name error
return;
}
}
if (inputData.phone && inputData.phone.value.trim() !== "") {
if (validator.isMobilePhone(inputData.phone.value, ["he-US"])) {
console.log("valid phone");
} else {
//phone error
return;
}
}
emailjs
.sendForm(
process.env.EMAILJS_SERVICE_ID,
process.env.EMAILJS_TEMPLATE_ID,
form.current,
process.env.EMAILJS_USER_ID
)
.then(
(result) => {
//do something with success
...
form.current.reset(); //not working!!!!!!
},
(error) => {
//do something with error
}
);
};
return (
...
<form ref={form} onSubmit={sendEmail}>
<div className={styles.footerFormRow}>
<TextInput
type="input"
label='דוא"ל'
name="from_email"
/>
<TextInput
type="input"
label="שם מלא"
name="full_name"
/>
<input type="text" name="somename" />
</div>
</form>
...
)
only the somename input is reset, the others in the functional component no.
any hepl?

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}...

Validation check in reactjs issue

Why I am not able to see validation alert clicking on the done button when everything is empty once form open even validation checks are proper ?
Basically form opens i don't type anything and click on done button so all validation checks should work and show text 'Required.Please enter your given name.' but it is not showing ?
Where is the issue which causes the state to be blank at the end
const addSecondaryContact = inject('apptContacts')(observer((props) => {
const {
i18n, nbnContact, apptContacts, backButtonContent,
} = props;
const { updatePrimaryContact } = apptContacts;
const CMS = i18n.appointmentManager.editAppointmentContact;
const [state, setState] = useState({
data: {
firstName: '',
lastName: '',
number: '',
},
firstNameValid: '',
lastNameValid: '',
numberValid: '',
});
const validFirstName = () => {
console.log(state.data.firstName);
if (!state.data.firstName) {
console.log('frstname1');
return 'Required.Please enter your given name.';
}
if (!/^[A-Za-z]+$/.test(state.data.firstName)) {
console.log('frstname2');
return 'Invalid entry.Please use letters only.';
} if (state.data.firstName.length === 1) {
console.log('frstname3');
return 'Invalid entry.More than one character is required';
}
console.log('&&&&');
return '';
};
const validLastName = () => {
console.log('988');
if (!state.data.lastName) { console.log('lastname'); return 'Required.Please enter your given name.'; }
if (!/^[A-Za-z]+$/.test(state.data.lastName)) {
return 'Invalid entry.Please use letters only.';
} if (state.data.lastName.length === 1) {
return 'Invalid entry.More than one character is required';
}
return '';
};
const validNumber = async () => {
console.log('777');
if (!state.data.number) { return 'Required.Please enter your mobile number.'; }
if (state.data.number.substr(0, 2) !== '04') {
return 'Invalid entry.Please enter your 10-digit mobile number starting with 04.';
} if (state.data.number.length !== 10) {
return 'Invalid entry.Please enter your 10-digit mobile number starting with 04.';
} if (state.data.number.length === 1) {
return 'Invalid entry.More than one number is required';
}
return '';
};
const valid = async () => {
console.log('milan');
setState({
...state,
firstNameValid: validFirstName(),
lastNameValid: validLastName(),
numberValid: validNumber(),
});
console.log(state.firstNameValid);
console.log(state.lastNameValid);
console.log(state.numberValid);
};
const handleTextareaChange = (event) => {
console.log('%%%');
const { data } = state;
data[event.target.name] = event.target.value;
setState({
...state,
data,
});
valid();
};
const saveButton = async () => {
console.log(state);
await valid();
if (valid()) {
console.log(state.firstNameValid);
console.log(state.lastNameValid);
console.log(state.numberValid);
if (!state.firstNameValid && !state.lastNameValid && !state.numberValid) {
const personName = `${state.data.firstName} ${state.data.lastName}`;
const primaryContact = {
name: personName,
phoneNumber: state.data.number,
// updatePrimaryContact(primaryContact)
};
// updatePrimaryContact(primaryContact)
backButtonContent();
}
}
};
return (
<div>
<VerticalSpacing size={ABLE_SPACING_SIZE.spacing4x} />
<h1 tabIndex="-1" className="HeadingB mt-sheet-heading">
{CMS.heading2}
</h1>
<VerticalSpacing size={ABLE_SPACING_SIZE.spacing3x} />
<TextField id="givenName" name="firstName" label={CMS.name} onChange={handleTextareaChange} value={state.data.firstName} />
{state.firstNameValid && (
<Alert variant="error" inline>
<p>
{state.firstNameValid}
</p>
</Alert>
)}
<VerticalSpacing size={ABLE_SPACING_SIZE.spacing3x} />
<TextField id="familyName" name="lastName" label={CMS.familyName} onChange={handleTextareaChange} value={state.data.lastName} />
{state.lastNameValid && (
<Alert variant="error" inline>
<p>
{state.lastNameValid}
</p>
</Alert>
)}
<VerticalSpacing size={ABLE_SPACING_SIZE.spacing3x} />
<TextField id="mobileNumber" name="number" label={CMS.mobile} onChange={handleTextareaChange} value={state.data.number} />
{state.numberValid && (
<Alert variant="error" inline>
<p>
{state.numberValid}
</p>
</Alert>
)}
<VerticalSpacing size={ABLE_SPACING_SIZE.spacing4x} />
<ActionButton className={styles.saveCta} variant="HighEmphasis" label={CMS.saveCTA} onClick={() => saveButton()} />
</div>
);
}));
export default addSecondaryContact;
You had two main issues:
you state update is not proper - you set state on multiple occasions
you had async in your validNumber method - which causes blank output
Here is the code i modify from your code - maybe it can help you. I removed extra components in order to remove dependencies and used only plain html.
Demo: https://codesandbox.io/s/upbeat-feynman-w3odj?file=/App.js
import "./styles.css";
import React from "react";
export default function App() {
const [state, setState] = React.useState({
data: {
firstName: "",
lastName: "",
number: ""
},
firstNameValid: "",
lastNameValid: "",
numberValid: ""
});
const validFirstName = () => {
console.log(state.data.firstName);
let result = "";
if (!state.data.firstName) {
console.log("frstname1");
result = "Required.Please enter your given name.";
}
if (!/^[A-Za-z]+$/.test(state.data.firstName)) {
console.log("frstname2");
result = "Invalid entry.Please use letters only.";
}
if (state.data.firstName.length === 1) {
console.log("frstname3");
result = "Invalid entry.More than one character is required";
}
console.log("&&&&");
return result;
};
const validLastName = () => {
console.log("988");
if (!state.data.lastName) {
console.log("lastname");
return "Required.Please enter your given name.";
}
if (!/^[A-Za-z]+$/.test(state.data.lastName)) {
return "Invalid entry.Please use letters only.";
}
if (state.data.lastName.length === 1) {
return "Invalid entry.More than one character is required";
}
return "";
};
const validNumber = () => {
console.log("777");
if (!state.data.number) {
return "Required.Please enter your mobile number.";
}
if (state.data.number.substr(0, 2) !== "04") {
return "Invalid entry.Please enter your 10-digit mobile number starting with 04.";
}
if (state.data.number.length !== 10) {
return "Invalid entry.Please enter your 10-digit mobile number starting with 04.";
}
if (state.data.number.length === 1) {
return "Invalid entry.More than one number is required";
}
return "";
};
const valid = async () => {
console.log("milan");
setState({
...state,
firstNameValid: validFirstName(),
lastNameValid: validLastName(),
numberValid: validNumber()
});
console.log(state.firstNameValid);
console.log(state.lastNameValid);
console.log(state.numberValid);
};
const handleTextareaChange = (event) => {
let validRes = "";
let key = "";
if (event.target.name === "firstName") {
validRes = validFirstName();
key = "firstNameValid";
}
if (event.target.name === "lastName") {
validRes = validLastName();
key = "firstNameValid";
}
if (event.target.name === "number") {
validRes = validNumber();
key = "numberValid";
}
console.log("234", validRes);
setState({
...state,
data: { ...state.data, [event.target.name]: event.target.value },
// [key]:
firstNameValid: validFirstName(),
lastNameValid: validLastName(),
numberValid: validNumber()
});
// valid();
};
const saveButton = async () => {
console.log(state);
await valid();
if (valid()) {
console.log(state.firstNameValid);
console.log(state.lastNameValid);
console.log(state.numberValid);
}
};
return (
<div>
<h1 tabIndex="-1" className="HeadingB mt-sheet-heading">
'CMS.heading2'
</h1>
<input
type="text"
id="givenName"
name="firstName"
label="CMS.name"
onChange={handleTextareaChange}
value={state.data.firstName}
/>
{state.firstNameValid && <p>{state.firstNameValid}</p>}
<input
type="text"
id="familyName"
name="lastName"
label="CMS.familyName"
onChange={handleTextareaChange}
value={state.data.lastName}
/>
{state.lastNameValid && <p>{state.lastNameValid}</p>}
<input
type="text"
id="mobileNumber"
name="number"
label="CMS.mobile"
onChange={handleTextareaChange}
value={state.data.number}
/>
{state.numberValid && <p>{state.numberValid}</p>}
<button
variant="HighEmphasis"
label="CMS.saveCTA"
onClick={() => saveButton()}
/>
</div>
);
}

Why can't I type anything into my form inputs

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" />

Unhandled Rejection (TypeError): Cannot read property 'push' of undefined aftering trying to do POST request

This error pops up in browser when trying to post:
newest error:
TypeError: Cannot read property 'push' of undefined
at SandwhichForm.js:30
at async SandwhichForm.handleFormSubmit (SandwhichForm.js:27)
Here is the full code:
import React from 'react';
import { Form, Input, Button } from 'antd';
import { connect } from "react-redux";
import axios from 'axios';
const FormItem = Form.Item;
class SandwhichForm extends React.Component {
handleFormSubmit = async (event, requestType, sandwhichID) => {
event.preventDefault();
const postObj = {
title: event.target.elements.title.value,
content: event.target.elements.content.value
}
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.headers = {
"Content-Type": "application/json",
Authorization: `Token ${this.props.token}`,
};
if (requestType === "post") {
await axios.post('http://127.0.0.1:8000/api_sandwhiches/create/', postObj)
.then(res => {
if (res.status === 201) {
this.props.history.push(`/`);
}
})
.catch(error => console.error(error));
} else if (requestType === "put") {
await axios.put(`http://127.0.0.1:8000/api_sandwhiches/${sandwhichID}/update/`, postObj)
.then(res => {
if (res.status === 200) {
this.props.history.push(`/`);
}
})
.catch(error => console.error(error));
}
};
render() {
return (
<div>
<Form
onSubmit={event =>
this.handleFormSubmit(
event,
this.props.requestType,
this.props.sandwhichID
)
}
>
<FormItem label="Title">
<Input name = "title" placeholder="Put a title here" />
</FormItem>
<FormItem label="Content">
<Input name="content" placeholder="Enter some content ..." />
</FormItem>
<FormItem >
<Button type="primary" htmlType="submit">
{this.props.btnText}
</Button>
</FormItem>
</Form>
</div>
);
}
}
const mapStateToProps = state => {
return {
token: state.token
};
};
export default connect(mapStateToProps)(SandwhichForm)
What is happening:
Information was posting and going to api
error now in console not browser
info is no longer posting

Categories