Formik Error Passing To Submit Not Working? - javascript

Hi guys i want to pass 'error' coming from nodejs backend to onsubmit the problem that even if the error passes i still navigate to login page
this is my code :
import "./form_inscription.css";
import { useState } from "react";
import { useFormik } from "formik";
import { validationSchemaBase } from "./formsScema";
//reactstrap componenets
import { FormGroup, Label, Input, Alert } from "reactstrap";
//icons and assets
import ArrowLeft from "../../../../assets/icons/Arrow-Left.png";
import { useDispatch, useSelector } from "react-redux";
// import { registerUser } from "../../../../store/features/authentication/inscription/inscriptionThunk";
import { registerUser } from "../../../../store/features/authentication/authentificationThunk";
import { useNavigate } from "react-router-dom";
import { Eye, EyeOff } from "react-feather";
import { useEffect } from "react";
const FormIscriptionEtape1 = () => {
const [checkboxError, setCheckboxError] = useState(false);
const [showPassword, setShowPassword] = useState(false);
const { error } = useSelector((store) => store.authentification);
const onSubmit = (values) => {
if (values.password === values.passConfirm) {
//checkbox error handling conditions
if (values.cPartner || values.aPartner || values.sPartner) {
setCheckboxError(false);
dispatch(registerUser(values));
if (!error) {
navigate("/login");
}
} else {
setCheckboxError(true);
}
//catch error handling
} else {
console.log("mot de passe non conforme!!");
}
};
const togglePasswordVisibility = () => {
setShowPassword((prevState) => !prevState);
};
const dispatch = useDispatch();
//formik data management
const {
values,
handleChange,
handleBlur,
handleSubmit,
setFieldValue,
errors,
touched,
} = useFormik({
initialValues: {
email: "",
password: "",
passConfirm: "",
cPartner: false,
aPartner: false,
sPartner: false,
},
validationSchema: validationSchemaBase.test(
"one check-box-required",
"Veuillez sélectionner le type de votre organsime",
(values) => values.aPartner || values.sPartner || values.cPartner
),
onSubmit,
});
//handle check boxes
const handleChangeBox = (event) => {
const { name, value, checked } = event.target;
if (name === "cPartner" || name === "aPartner" || name === "sPartner") {
setFieldValue(name, checked);
if (name === "cPartner") {
setFieldValue("aPartner", false);
setFieldValue("sPartner", false);
setCheckboxError(false);
} else if (name === "aPartner") {
setFieldValue("cPartner", false);
setFieldValue("sPartner", false);
setCheckboxError(false);
} else {
setFieldValue("cPartner", false);
setFieldValue("aPartner", false);
setCheckboxError(false);
}
} else {
setFieldValue(name, value);
setCheckboxError(false);
}
};
//navigation to Login screen through the back button temporary will be deleted in the future
const navigate = useNavigate();
const handleNavigateLogin = () => {
navigate("/login");
};
return (
<div>
<div className="w-100 d-flex flex-column justify-content-center align-items-center">
<div className="w-50 mb-1">
<FormGroup className="mt-2">
<Label
className="label_title_inscription text_600_nrm"
for="exampleEmail"
>
Email
</Label>
<Input
className="input_text_off"
type="email"
name="email"
value={values.email}
onChange={handleChange}
onBlur={handleBlur}
/>
{errors.email && (
<p className="validation_problems">{errors.email}</p>
)}
</FormGroup>
</div>
<div className="w-50 mb-1">
<div className=" justify-content-between">
<FormGroup className="auth-login-form mt-2">
<Label
className="label_title_inscription text_600_nrm"
for="examplePassword"
>
Mot de passe
</Label>
<Input
className="input_text_off"
type={showPassword ? "text" : "password"}
name="password"
value={values.password}
onChange={handleChange}
onBlur={handleBlur}
/>
{/* <div
className="password-visibility-icon"
onClick={togglePasswordVisibility}
>
{showPassword ? <Eye size={20} /> : <EyeOff size={20} />}
</div> */}
{errors.password && touched.password && (
<p className="validation_problems">{errors.password}</p>
)}
</FormGroup>
</div>
</div>
<div className="w-50 mb-1">
<div className=" justify-content-between">
<FormGroup className="auth-login-form mt-2">
<Label
className="label_title_inscription text_600_nrm"
for="examplePassword"
>
Confirmation mot de passe
</Label>
<Input
className="input_text_off"
type={showPassword ? "text" : "password"}
name="passConfirm"
value={values.passConfirm}
onChange={handleChange}
onBlur={handleBlur}
/>
{/* <div
className="password-visibility-icon"
onClick={togglePasswordVisibility}
>
{showPassword ? <Eye size={20} /> : <EyeOff size={20} />}
</div> */}
{errors.passConfirm && touched.passConfirm && (
<p className="validation_problems">{errors.passConfirm}</p>
)}
</FormGroup>
</div>
</div>
</div>
{/* checkbox section */}
<p className="text-center mt-5 checkbox_text_inscription text_600_nrm">
Vous êtes
</p>
{checkboxError && (
<p className="validation_problems error_validation_check">
Veuillez sélectionner le type de votre organsime
</p>
)}
<div className="d-flex justify-content-center checkbox">
<div className="form-check d-flex checks_gap">
<Input
type="checkbox"
className="form-check"
name="cPartner"
checked={values.cPartner}
onChange={handleChangeBox}
/>
<Label
className="form-check-Label checkbox_text_inscription text_600_nrm"
htmlFor="formrow-customCheck"
>
Commercial
</Label>
</div>
<div className="form-check d-flex checks_gap">
<Input
type="checkbox"
className="form-check"
name="sPartner"
checked={values.sPartner}
onChange={handleChangeBox}
/>
<Label
className="form-check-Label checkbox_text_inscription text_600_nrm"
htmlFor="formrow-customCheck"
>
Educatif
</Label>
</div>
<div className="form-check d-flex checks_gap">
<Input
type="checkbox"
className="form-check"
name="aPartner"
checked={values.aPartner}
onChange={handleChangeBox}
/>
<Label
className="form-check-Label checkbox_text_inscription text_600_nrm"
htmlFor="formrow-customCheck"
>
Associatif
</Label>
</div>
</div>
{error ? <Alert color="danger">{error.message}</Alert> : null}{" "}
<div className="w-100 d-flex justify-content-end mt-5">
{/* <button
className="d-flex align-items-center justify-content-center btn_next_back"
onClick={handleNavigateLogin}
>
<img src={ArrowLeft} alt="" />
</button> */}
<button type="submit" className="btn_next_step" onClick={handleSubmit}>
Suivant
</button>
</div>
</div>
);
};
export default FormIscriptionEtape1;
i tried passing error to onsubmit props but it gives me undefined everytime so the only way that my error passes is the way i am writing the code right now.

Maybe it's because of this typo?
(store) => store.authentification
it should probably be "authentication"
(store) => store.authentication

Related

How to trigger modal from a different component

1st component (here is the modal)
import './Register.css';
import {useFormik} from 'formik';
import * as Yup from 'yup';
import {useNavigate} from 'react-router-dom';
import {registerUser} from '../../services/auth.service';
import {
createUser,
getUserByUsername,
} from '../../services/user.request.services.js';
import {useContext} from 'react';
import AppContext from '../../context/AppContext.js';
export default function Register() {
const navigate = useNavigate();
const {addToast} = useContext(AppContext);
const formik = useFormik({
initialValues: {
username: '',
firstName: '',
lastName: '',
email: '',
password: '',
},
validationSchema: Yup.object({
username: Yup.string()
.max(50, 'Username must be maximum 50 symbols')
.required('Please, choose username.')
.min(4, 'username must be minimum 4 symbols'),
firstName: Yup.string()
.max(32, 'Last name must be maximum 32 symbols')
.min(4, 'First name must be minimum 4 symbols')
.required('You need to apply first name!'),
lastName: Yup.string()
.max(32, 'First name must be maximum 32 symbols')
.min(4, 'Last name must be minimum 4 symbols')
.required('You need to apply last name!'),
email: Yup.string()
.email('Must be a valid email address')
.required('Email is required!'),
password: Yup.string().required('Please, type your password.'),
}),
onSubmit: async (values) => {
try {
const user = await getUserByUsername(values.username);
if (user !== null) {
formik.errors.username = 'Username already in use!';
return;
}
const credentials = await registerUser(values.email, values.password);
try {
await createUser(
values.firstName,
values.lastName,
values.email,
values.username,
credentials.user.uid,
);
} catch (error) {
addToast('error', 'Something went wrong!');
}
} catch (error) {
if (error.message.includes('auth/email-already-in-use')) {
formik.errors.email = 'This email is already in use!';
return;
}
addToast('error', 'Something went wrong');
}
addToast('success', 'You have been registered!');
addToast('success', 'Welcome to the UnHOOman Forum!');
navigate('/');
},
});
const resetFormHandler = () => {
formik.resetForm();
};
return (
<>
<label htmlFor="register-modal">
<p className="cursor-pointer">Register</p>
</label>
<input type="checkbox" id="register-modal" className="modal-toggle" />
<div className="modal modal-bottom sm:modal-middle">
<div className="modal-box min-h-1/2">
<div className="modal-action m-0 justify-center gap-2 h-full border-2 border-[#F79E47]">
<form onSubmit={formik.handleSubmit} className="w-full">
<div className='form-wrapper'>
<h1 className="font-bold">Register</h1>
<input
type="text"
placeholder="Username..."
name="username"
value={formik.values.username}
onBlur={formik.handleBlur}
onChange={formik.handleChange}
className="input w-full input-bordered border-[#F79E47] max-w-xs block"
/>
{formik.touched.username && formik.errors.username ? (
<p className="text-red-700 text-sm">{formik.errors.username}</p>
) : null}
<input
type="text"
placeholder="First name..."
name="firstName"
value={formik.values.firstName}
onBlur={formik.handleBlur}
onChange={formik.handleChange}
className="input input-bordered border-[#F79E47] w-full max-w-xs"
/>
{formik.touched.firstName && formik.errors.firstName ? (
<p className="text-red-700 text-sm">{formik.errors.firstName}</p>
) : null}
<input
type="text"
placeholder="Last name..."
name="lastName"
value={formik.values.lastName}
onBlur={formik.handleBlur}
onChange={formik.handleChange}
className="input input-bordered border-[#F79E47] w-full max-w-xs"
/>
{formik.touched.lastName && formik.errors.lastName ? (
<p className="text-red-700 text-sm">{formik.errors.lastName}</p>
) : null}
<input
type="email"
placeholder="Email..."
name="email"
value={formik.values.email}
onBlur={formik.handleBlur}
onChange={formik.handleChange}
className="input input-bordered border-[#F79E47] w-full max-w-xs"
/>
{formik.touched.email && formik.errors.email ? (
<p className="text-red-700 text-sm">{formik.errors.email}</p>
) : null}
<input
type="password"
placeholder="Password..."
name="password"
value={formik.values.password}
onBlur={formik.handleBlur}
onChange={formik.handleChange}
className="input input-bordered border-[#F79E47] w-full max-w-xs"
/>
{formik.touched.password && formik.errors.password ? (
<p className="text-red-700 text-sm">{formik.errors.password}</p>
) : null}
<div className="signup-buttons">
<label
type="button"
htmlFor="register-modal"
className="btn btn-outline"
onClick={() => resetFormHandler()}
>
CANCEL
</label>
<button type="submit" className="btn btn-outline">
Submit
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</>
);
}
2nd component from which I want to be able to trigger the modal
import {HOME_CARD_TITLE, HOME_CARD_DESC} from '../../common/constants.js';
import {useContext, useEffect, useState} from 'react';
import {getAllPosts} from '../../services/posts.service.js';
import {getAllUsers} from '../../services/user.request.services.js';
import AppContext from '../../context/AppContext.js';
import {Navigate, useNavigate} from 'react-router-dom';
export default function HomeInfoCard() {
const [cardState, setCardState] = useState({posts: 0, members: 0});
const {addToast} = useContext(AppContext);
const navigate = useNavigate();
useEffect(() => {
const updatePostsAndUsers = async () => {
const posts = (await getAllPosts()).length;
const members = (await getAllUsers()).length;
setCardState((prev) => ({
...prev,
posts,
members,
}));
};
updatePostsAndUsers().catch((error) => addToast('error', error.message));
}, []);
return (
<div className="card max-w-md bg-base-100 shadow-xl">
<div className="card-body">
<h2 className="card-title">{ HOME_CARD_TITLE }</h2>
<p className="mb-3">{ HOME_CARD_DESC }</p>
<div className="stats shadow text-center mb-3">
<div className="stat">
<div className="stat-title">Posts</div>
<div className="stat-value">{ cardState.posts }</div>
</div>
<div className="stat">
<div className="stat-title">Members</div>
<div className="stat-value">{ cardState.members }</div>
</div>
</div>
<div className="card-actions justify-center">
<button className="btn bg-[#FCDDBF] border-0 text-[#4A4846] hover:text-[#fff] w-full" onClick={() => navigate('/login')}>Join community</button>
</div>
</div>
</div>
);
}
I have two components, the first one is a register form with Formik and there is also a modal from daisyUI.
I have a 'View community button' in other component which I want to be able to make on click to open the register form modal from the other component, but I couldn't find a solution for this problem.
I've tried with data-toggle/data-target, but it didn't work.
The button which I want to be able to trigger the modal from the register component is in the end of the second component and it's currently leading to the home page with useNavigate.
I am not a professional programmer, and currently I am in a boot camp, so that's why the code is trashy, but we all start from somewhere. Thanks in advance for the replies!

React - multi step form with checkbox in child step does not set to true

I am creating a multistep form in react. The Parent component has 3 child components which are the steps of the form. In the first step I have 4 text inputs and need a checkbox to allow wpp communication, the problem is that i can't set the state of the checkbox to true when is clicked.
The parent component is something like this:
import React from 'react';
import FormStep0 from './formStepZero';
import FormStep1 from './formStepOne';
class VendeForm extends React.Component {
constructor(props) {
super(props)
this.state = {
currentStep: 0,
nombre: '',
apellido: '',
celular: '',
email: '',
username: '',
password: '',
checkbox: false,
}
}
handleChange = event => {
const {name, value} = event.target
this.setState({
[name]: value
})
}
handleSubmit = event => {
event.preventDefault()
const { email, username, password, nombre, apellido, celular,checkbox } = this.state
alert(`Your registration detail: \n
Email: ${email} \n
Username: ${username} \n
Password: ${password} \n
Nombre: ${nombre} \n
Apellido: ${apellido} \n
Celular: ${celular} \n
Checkbox: ${checkbox} \n`)
}
_next = () => {
let currentStep = this.state.currentStep
currentStep = currentStep >= 2? 3: currentStep + 1
this.setState({
currentStep: currentStep
})
}
_prev = () => {
let currentStep = this.state.currentStep
currentStep = currentStep <= 0? 0: currentStep - 1
this.setState({
currentStep: currentStep
})
}
/*
* the functions for our button
*/
previousButton() {
let currentStep = this.state.currentStep;
if(currentStep > 1){
return (
<div className='vertical-center'>
<button
className="btn btn-secondary float-right mx-2 my-2"
type="button" onClick={this._prev}>
Previous
</button>
</div>
)
}
return null;
}
nextButton(){
let currentStep = this.state.currentStep;
if(currentStep <3 && currentStep >=1){
return (
<div className='vertical-center'>
<button
className="btn primary-bg-style float-left mx-2 my-2"
type="button" onClick={this._next}>
Siguiente
</button>
</div>
)
}
return null;
}
empecemosButton(){
let currentStep = this.state.currentStep;
if(currentStep === 0){
return (
<div className='vertical-center'>
<button
className="btn primary-bg-style"
type="button" onClick={this._next}>
Vamos!
</button>
</div>
)
}
return null;
}
render() {
return (
<React.Fragment>
{/*render the form steps and pass required props in*/}
<Step0
currentStep={this.state.currentStep}
handleChange={this.handleChange}
/>
<div className="container d-flex flex-column py-2">
<form onSubmit={this.handleSubmit}>
<Step1
currentStep={this.state.currentStep}
handleChange={this.handleChange}
nombre={this.state.nombre}
apellido={this.state.apellido}
celular={this.state.celular}
email={this.state.email}
checkbox={this.state.checkbox}
/>
<Step2
currentStep={this.state.currentStep}
handleChange={this.handleChange}
username={this.state.username}
/>
<Step3
currentStep={this.state.currentStep}
handleChange={this.handleChange}
password={this.state.password}
/>
</form>
<div className='prev-next-btn'>
{this.previousButton()}
{this.nextButton()}
</div>
{this.empecemosButton()}
</div>
</React.Fragment>
);
}
}
function Step0(props){
if (props.currentStep !== 0) {
return null
}
return(
<div className="vertical-center"> {/*<!--^--- Added class --> */}
...
</div>
)
}
function Step1(props) {
if (props.currentStep !== 1) {
return null
}
return(
<div className="form-group">
<div className="vertical-center">
<div className="container">
<h1 className='pb-4 px-2'>Datos de Contacto</h1>
<CircleSteps currentStep={props.currentStep} />
<FormStep1 nombre={props.nombre}
apellido={props.apellido}
celular={props.celular}
email={props.email}
checkbox={props.checkbox}
handleChange = {props.handleChange}
/>
</div>
</div>
</div>
);
}
export default VendeForm;
and the child component where is the checkbox is:
import React from 'react';
import {Col, Row,Container} from 'reactstrap'
function FormStep1(props) {
return(
<div>
<Container className="vende-form-container pt-3">
<Row className='align-items-center justify-content-center'>
<Col md={4} sm={12}>
<div className="form-group">
<label htmlFor="nombre">Nombre</label>
<input
className="form-control"
id="nombre"
name="nombre"
type="text"
placeholder="Escribe tu nombre"
value={props.nombre}
onChange={props.handleChange}
/>
</div>
</Col>
<Col md={4} sm={12} >
<div className="form-group">
<label htmlFor="apellido">Apellido</label>
<input
className="form-control"
id="apellido"
name="apellido"
type="text"
placeholder="Escribe tu apellido"
value={props.apellido}
onChange={props.handleChange}
/>
</div>
</Col>
</Row>
<Row className='align-items-center justify-content-center'>
<Col md={4} sm={12}>
<div className="form-group">
<label htmlFor="celular">Celular</label>
<input
className="form-control"
id="celular"
name="celular"
type="text"
placeholder="Escribe tu celular"
value={props.celular}
onChange={props.handleChange}
/>
</div>
</Col>
<Col md={4} sm={12}>
<div className="form-group">
<label htmlFor="email">Email</label>
<input
className="form-control"
id="email"
name="email"
type="text"
placeholder="Escribe tu email"
value={props.email}
onChange={props.handleChange}
/>
</div>
</Col>
</Row>
<Row className='align-items-center justify-content-start'>
{/* checkbox allowing whatsapp communication */}
<Col sm={{size:6, offset:2}} md={{size:3, offset:2}}>
<div className="form-check">
<input
className="form-check-input"
id="wppCheckbox"
name="controlled"
type="checkbox"
checked={props.checkbox}
onChange={props.handleChange}
/>
<label className="form-check-label" htmlFor="wppCheckbox">
Aceptas comunicacion via Whatsapp
</label>
</div>
</Col>
</Row>
</Container>
</div>
);
}
export default FormStep1;
The behavior that currently I have is that i click the checkbox but remains in blank, also the others fields of the form are working well and are passed to state properly
If I understand correctly, your checkbox is handled by generic handleChange() function:
handleChange = event => {
const {name, value} = event.target
this.setState({
[name]: value
})
}
Simplest thing you could try for debugging is just logging what you get in that function when you click the checkbox. Most probably in this case you are always getting the same value ("on") hence nothing changes in the state.
I would suggest either use a dedicated handler, or modify this one to be sth like
handleChange = event => {
const {name, type, value} = event.target
if (type === 'checkbox') {
return this.setState({
[name]: event.target.checked
})
}
this.setState({
[name]: value
})
}

How can I get input value from react-form-hook for out of the form?

I used react-form-hook to implement login form. now I want to that email input value on a state for clicking on the forget password . from onSubmit function I use a state for props value. if I get the value I have to click to the form login. but forget password button is out of the form login section. so I want onChange on the email input . I don't want to get email value from clicking login button then forget button.
const Login = () => {
const [signInWithGoogle, googleUser, googleLoading, googleError] = useSignInWithGoogle(auth);
const location = useLocation();
const navigate = useNavigate();
const from = location.state?.from?.pathname || "/";
const [formData, setFormData] = useState('');
console.log(formData);
const [
signInWithEmailAndPassword,
user,
loading,
error,
] = useSignInWithEmailAndPassword(auth);
const handleGoogleSignIn = () => {
signInWithGoogle();
}
const [sendPasswordResetEmail, sending, resetPasswordError] = useSendPasswordResetEmail(auth);
const handlePasswordReset = async () => {
if (error?.message === 'MISSING_EMAIL' || formData === '') {
return <div>{resetPasswordError && resetPasswordError.message}
<h6>{error && error.message}</h6>
</div>
} else {
await sendPasswordResetEmail(formData);
toast('sent email')
}
console.log(formData);
}
// console.log(formData);
const { register, handleSubmit, formState: { errors } } = useForm();
if (user || googleUser) {
navigate(from, { replace: true });
}
const onSubmit = data => {
console.log(data)
setFormData(data.email);
signInWithEmailAndPassword(data.email, data.password);
};
// console.log(errors);
return (
<div>
<div>
<h2 className='text-primary fw-bold text-center my-5'>Please Login To Continue</h2>
<div className='container'>
<form onSubmit={handleSubmit(onSubmit)}>
<div className='my-4 w-50 mx-auto'>
<label className="form-label fw-bold">Email address</label>
{/* onChange={event => setEmail(event.target.value)} */}
<input className='form-control' onChange={(e) => console.log(e.target.value)} name='email' type="email" placeholder="email" {...register("email", {
required: true, pattern: /^\S+#\S+$/i
})} />
<p className='fw-bold text-danger'>
{errors?.email && "*Enter a Valid Email"}
</p>
</div>
<div className='my-4 w-50 mx-auto'>
<label className="form-label fw-bold">Password</label>
<input className='form-control' name='password' type="password" placeholder="password" {...register("password", { required: false, max: 0, min: 6, maxLength: 12, pattern: /.{6,}/i })} />
<p className='fw-bold text-danger'>
{errors?.password && "*Enter a Valid Password"}
</p>
</div>
{error && <h6 className='fw-bold text-danger text-center my-2'>{error?.message}</h6>}
<div className='text-center text-center my-3'>
{loading && <Spinner></Spinner>}
</div>
<div className='w-50 mx-auto mt-4 mb-5'>
<button className='form-control btn btn-primary fw-bold' type="submit">Login</button>
</div>
</form>
<div className='text-center my-2'>
{sending && <Spinner></Spinner>}
</div>
<div className='text-center fw-bold text-danger mb-3'>
<p className=''>{resetPasswordError?.message && resetPasswordError?.message} </p>
{resetPasswordError?.message && 'Need Valid Email'}
</div>
<div className='text-center'>
<p className='fw-bold'>If you don't have an account, <Link to='/register'>Click on Register</Link></p>
<p className='fw-bold' onClick={handlePasswordReset}>Forget Password? <Link to>Reset Password</Link></p>
</div>
<div className='d-flex justify-content-center my-5'>
<div style={{ height: '2px' }} className='w-25 bg-danger mt-2 me-1'></div>
<span className=''>or</span>
<div style={{ height: '2px' }} className='w-25 bg-danger mt-2 me-1'></div>
</div>
{/* googleLoading, googleError */}
<div className='text-center my-2'>
{googleLoading && <Spinner></Spinner>}
</div>
{googleError && <h6 className='fw-bold text-danger text-center my-2'>{googleError?.message}</h6>}
<div className='text-center mb-5'>
<button className='btn btn-danger fw-bold' onClick={handleGoogleSignIn}>Sign in with Google</button>
</div>
</div>
</div>
</div>

Uncaught TypeError: Cannot read properties of undefined (reading 'roll')

I keep running into this error. I have tried defining the variables but it still does not seem to work. I may be doing this wrong or its something very small but i cant seem to figure it out. I would appreciate the help.
Uncaught ReferenceError: process is not defined
this is another error which im guessing is from the same issue.
This is my code below:
import React, { Component } from "react";
import { Button, Form, FormGroup, Label, Input, Col, Row } from "reactstrap";
import Loading from "./LoadingComponent";
class Issue extends Component {
constructor(props) {
super(props);
this.state = {
isbn: "",
roll: "",
};
}
componentDidMount() {
window.scrollTo(0, 0);
}
render() {
if (this.props.booksLoading || this.props.usersLoading) {
return (
<div className="container">
<div className="row">
<Loading />
</div>
</div>
);
} else if (this.props.booksErrMess) {
return (
<div className="container loading">
<div className="row heading">
<div className="col-12">
<br />
<br />
<br />
<br />
<h3>{this.props.booksErrMess}</h3>
</div>
</div>
</div>
);
} else if (this.props.usersErrMess) {
return (
<div className="container loading">
<div className="row heading">
<div className="col-12">
<br />
<br />
<br />
<br />
<h3>{this.props.usersErrMess}</h3>
</div>
</div>
</div>
);
}
else {
const bookoptions = this.props.books.map((book, index) => (
<option key={book.isbn}>{book.isbn}</option>
));
const defaultBook = this.props.books[0];
// To just get list of the students (not the admins)
let useroptions = this.props.users.filter((user) => !user.admin);
const defaultUser = useroptions[0];
useroptions = useroptions.map((user, index) => (
<option key={user.roll}>{user.roll}</option>
));
if (this.state.isbn === "") {
this.setState({ isbn: defaultBook.isbn, roll: defaultUser.roll });
}
return (
<div className="container full">
<div className="row justify-content-center heading">
<div className="col-12">
<h3 align="center"> Issue book</h3>
</div>
</div>
<div className="row row-content justify-content-center">
<Form
onSubmit={(e) => {
let bookid = this.props.books.filter(
(book) => book.isbn === this.state.isbn
)[0]._id;
let studentid = this.props.users.filter(
(user) => user.roll === this.state.roll
)[0]._id;
this.props.postIssue(bookid, studentid);
e.preventDefault();
}}
>
<FormGroup row>
<Label htmlFor="isbn"> ISBN No.of book</Label>
<Input
type="select"
defaultValue={defaultBook.name}
name="isbn"
id="isbn"
className="form-control"
onInput={(e) => {
this.setState({ isbn: e.target.value });
}}
>
{bookoptions}
</Input>
</FormGroup>
<FormGroup row>
<Label htmlFor="roll"> Roll No. of student </Label>
<Input
type="select"
id="roll"
className="form-control"
onInput={(e) => {
this.setState({ roll: e.target.value });
}}
>
{useroptions}
</Input>
</FormGroup>
<FormGroup row>
<Label htmlFor="name"> Name of book </Label>
<Input
type="text"
id="name"
name="name"
placeholder="Name of Book"
defaultValue={defaultBook.name}
value={
!this.state.isbn
? ""
: this.props.books.filter(
(book) => book.isbn === this.state.isbn
)[0].name
}
className="form-control"
disabled
/>
</FormGroup>
<FormGroup row>
<Label htmlFor="author"> Authors </Label>
<Input
type="text"
id="author"
name="author"
placeholder="Name of authors"
defaultValue={defaultBook.author}
value={
!this.state.isbn
? ""
: this.props.books.filter(
(book) => book.isbn === this.state.isbn
)[0].author
}
className="form-control"
disabled
/>
</FormGroup>
<FormGroup row>
<Label htmlFor="name_student"> Name of student </Label>
<Input
type="text"
id="name_student"
name="name_student"
placeholder="Name of student"
defaultValue={
defaultUser.firstname + " " + defaultUser.lastname
}
value={
!this.state.roll
? ""
: this.props.users.filter(
(user) => user.roll === this.state.roll
)[0].firstname +
" " +
this.props.users.filter(
(user) => user.roll === this.state.roll
)[0].lastname
}
className="form-control"
disabled
/>
</FormGroup>
<FormGroup row>
<Label htmlFor="username"> Username of student </Label>
<Input
type="text"
id="username"
name="username"
placeholder="Username of student"
defaultValue={defaultUser.username}
value={
!this.state.roll
? ""
: this.props.users.filter(
(user) => user.roll === this.state.roll
)[0].username
}
className="form-control"
disabled
/>
</FormGroup>
<Row className="align-self-center">
<Col className="text-center">
<Button type="submit" className="bg-primary">
Submit
</Button>
</Col>
</Row>
</Form>
</div>
<br />
</div>
);
}
}
}
export default Issue;
Since the error is reading from undefined, the only possible source of error should be user.roll or defaultUser.roll.
let useroptions = this.props.users.filter((user) => !user.admin);
const defaultUser = useroptions[0];
useroptions = useroptions.map((user, index) => (
<option key={user.roll}>{user.roll}</option>
));
Add an undefined check before using defaultUser and useroptions.
if (defaultUser) {
...
}

TypeError: path.split is not a function getting Error?

I'm trying to build a restaurant website. I already build half part of it. But I'm stuck at some point. I'm getting errors. I can't find out in my code what is wrong. Whenever I tried to add new food by clicking add button it added but whenever I click on the cart button to checkout visit the checkout page. Then I get:
TypeError: path.split is not a function?.
I'm using react hook form. I tried to debug but I'm getting the same errors many times. Can someone check it out, please?
Here is my App.js File
import logo from './logo.svg';
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import './App.css';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css'
import Banner from './components/Banner/Banner';
import Header from './components/Header/Header';
import Foods from './components/Foods/Foods';
import Features from './components/Features/Features';
import Footer from './components/Footer/Footer';
// import SIgnUp from './components/SignUp/SIgnUp';
import NotFound from './components/NotFound/NotFound';
import FoodItemDetails from './components/FoodItemDetails/FoodItemDetails'
import { createContext, useContext, useState } from 'react';
import Login from './components/Login/Login';
import PrivateRoute from './components/PrivateRoute/PrivateRoute';
import Shipment from './components/Shipment/Shipment';
export const userContext = createContext();
function App() {
const [cart , setCart] = useState([]);
const [orderId , setOrderId] = useState(null);
const [deliveryDetails , setDeliveryDetails] = useState({
todoor:null,road:null, flat:null, businessname:null, address: null
});
const [userEmail, setUserEmail] = useState(null);
const deliveryDetailsHandler = (data) => {
setDeliveryDetails(data)
}
const getUserEmail = (email) => {
setUserEmail(email);
}
const clearCart = () => {
const orderedItems = cart.map(cartItem => {
return {food_id : cartItem.id, quantity: cartItem.quantity}
})
const orderDetailsData = { userEmail , orderedItems, deliveryDetails }
fetch('https://red-onion-backend.herokuapp.com/submitorder' , {
method : "POST",
headers: {
"Content-type" : "application/json"
},
body : JSON.stringify(orderDetailsData)
})
.then(res => res.json())
.then(data=> setOrderId(data._id))
console.log(orderId);
setCart([])
}
const cartHandler = (data) => {
const alreadyAdded = cart.find(crt => crt.id == data.id );
const newCart = [...cart,data]
setCart(newCart);
if(alreadyAdded){
const reamingCarts = cart.filter(crt => cart.id != data);
setCart(reamingCarts);
}else{
const newCart = [...cart,data]
setCart(newCart);
}
}
const checkOutItemHandler = (productId, productQuantity) => {
const newCart = cart.map(item => {
if(item.id == productId){
item.quantity = productQuantity;
}
return item;
})
const filteredCart = newCart.filter(item => item.quantity > 0)
setCart(filteredCart)
}
const [logggedInUser, setLoggedInUser] = useState({});
const [signOutUser, setSignOutUser] = useState({});
return (
<userContext.Provider value={([logggedInUser, setLoggedInUser], [signOutUser, setSignOutUser])}>
<Router>
<div className="App">
<Switch>
<Route exact path="/">
<Header cart={cart}></Header>
<Banner></Banner>
<Foods cart={cart}></Foods>
<Features></Features>
<Footer></Footer>
</Route>
<Route path="/user">
<Login></Login>
</Route>
<Route path= "/food/:id">
<Header cart={cart}></Header>
{/* <FoodItemDetails cart={cart} cartHandler={cartHandler}></FoodItemDetails> */}
<FoodItemDetails cart={cart} cartHandler={cartHandler}></FoodItemDetails>
<Footer></Footer>
</Route>
<PrivateRoute path="/checkout">
<Header cart={cart}></Header>
<Shipment deliveryDetails={deliveryDetails} deliveryDetailsHandler={deliveryDetailsHandler} cart={cart} clearCart={clearCart} checkOutItemHandler={checkOutItemHandler} getUserEmail={getUserEmail}>
</Shipment>
<Footer></Footer>
</PrivateRoute>
<Route path ="*">
<NotFound></NotFound>
</Route>
</Switch>
</div>
</Router>
</userContext.Provider>
);
}
export default App;
Here is my Shipment.js File
import React from 'react';
import { useForm } from 'react-hook-form';
import { Link } from 'react-router-dom';
const Shipment = (props) => {
const { register, handleSubmit, watch, errors } = useForm();
const onSubmit = data => {
props.deliveryDetailsHandler(data);
// props.getUserEmail(auth.user.email);
};
const { todoor, road, flat, businessname, address} = props.deliveryDetails;
const subTotal = props.cart.reduce((acc,crr) => {
return acc + (crr.price * crr.quantity) ;
},0)
const totalQuantity = props.cart.reduce((acc,crr) => {
return acc + crr.quantity ;
},0)
const tax = (subTotal / 100) * 5;
const deliveryFee = totalQuantity && 2;
const grandTotal = subTotal + tax + deliveryFee;
return (
<div className="shipment container pt-5 my-5">
<div className="row">
<div style={{display:(todoor && road && flat && businessname && address) ? "none" : "block"}} className="col-md-5">
<h4>Edit Delivery Details</h4>
<hr/>
<form onSubmit={handleSubmit(onSubmit)} className="py-5">
<div className="form-group">
<input name="todoor" className="form-control" {...register( {requried: true})} defaultValue={todoor} placeholder="Delivery To Door"/>
{errors && errors.todoor && <span className="error">This Option is required</span>}
</div>
<div className="form-group">
<input name="road" className="form-control" {...register( {requried: true})} defaultValue={road} placeholder="Road No"/>
{errors && errors.road && <span className="error">Road No is required</span>}
</div>
<div className="form-group">
<input name="flat" className="form-control" {...register( {requried: true})} defaultValue={flat} placeholder="Flat, Suite or Floor"/>
{errors && errors.flat && <span className="error">Flat, Suite or Floor is required</span>}
</div>
<div className="form-group">
<input name="businessname" className="form-control" {...register( {requried: true})} defaultValue={businessname} placeholder="Business name"/>
{errors && errors.businessname && <span className="error">Business name is required</span>}
</div>
<div className="form-group">
<textarea name="address" {...register( {requried: true})} placeholder="Address" className="form-control" cols="30" rows="2">{address}</textarea>
{errors.address && <span className="error">Password is required</span>}
</div>
<div className="form-group">
<button className="btn btn-danger btn-block" type="submit">Save & Continue</button>
</div>
</form>
</div>
<div style={{display:(todoor && road && flat && businessname && address) ? "block" : "none"}} className="col-md-5">
{/* <Elements stripe={stripePromise}>
<Payment markAsPaid={markAsPaid}/>
</Elements> */}
</div>
<div className="offset-md-2 col-md-5">
<div className="restaurant-info mb-5">
<h4>Form <strong> Star Kabab And Restaura</strong></h4>
<h5>Arriving in 20-30 min</h5>
<h5>107 Rd No 9</h5>
</div>
{
props.cart.map(item =>
<div className="single-checkout-item mb-3 bg-light rounded d-flex align-items-center justify-content-between p-3">
<img width="100px" src={item.images[0]} alt=""/>
<div>
<h6>{item.name}</h6>
<h4 className="text-danger">${item.price.toFixed(2)}</h4>
<p>Delivery free</p>
</div>
<div className="checkout-item-button ml-3 btn">
<button onClick={() => props.checkOutItemHandler(item.id, (item.quantity+1)) } className="btn font-weight-bolder">+</button>
<button className="btn bg-white rounded">{item.quantity}</button>
{
item.quantity > 0 ?
<button className="btn font-weight-bolder" onClick={() => props.checkOutItemHandler(item.id, (item.quantity -1) )}>-</button>
:
<button disabled className="btn font-weight-bolder">-</button>
}
</div>
</div>
)
}
<div className="cart-calculation">
<p className="d-flex justify-content-between"><span>Sub Total . {totalQuantity} Item</span> <span>${subTotal.toFixed(2)}</span></p>
<p className="d-flex justify-content-between"><span>Tax</span> <span>${tax.toFixed(2)}</span></p>
<p className="d-flex justify-content-between"><span>Delivery Fee</span> <span>${deliveryFee}</span></p>
<p className="h5 d-flex justify-content-between"><span>Total</span> <span>${grandTotal.toFixed(2)}</span></p>
{/* {
totalQuantity ?
paid?
<Link to="/order-complete">
<button onClick={() => props.clearCart()} className="btn btn-block btn-danger btn-secondary">Check Out Your Food</button>
</Link>
:
<button disabled className="btn btn-block btn-secondary">Check Out Your Food</button>
:
<button disabled className="btn btn-block btn-secondary">Nothing to Checkout</button>
} */}
</div>
</div>
</div>
</div>
//
// <div className="shipment container">
// <h1>This is shipment</h1>
// <div className="row">
// <div className="">
// <h4>Edit Delivery Details</h4>
// <hr/>
// <form action="" className="py-5">
// <div className="form-group">
// <input type="text" name="todoor" className="form-control" ref={register({required: true})} defaultValue={todoor} placeholder="Delver to door" />
// {errors && errors.todoor && <span className="error">This Option is required</span>}
// </div>
// <div className="form-group">
// <input type="text" name="road" className="form-control" ref={register({required: true})} defaultValue={road} placeholder="Road No" />
// {errors && errors.road && <span className="error">This Option is required</span>}
// </div>
// <div className="form-group">
// <input type="text" name="flat" className="form-control" ref={register({required: true})} defaultValue={flat} placeholder="Flat, Suit Or Floor" />
// {errors && errors.flat && <span className="error">This Option is required</span>}
// </div>
// <div className="form-group">
// <input type="text" name="business" className="form-control" ref={register({required: true})} defaultValue={business} placeholder="Business Name" />
// {errors && errors.todoor && <span className="error">This Option is required</span>}
// </div>
// <div className="form-group">
// <input type="text" name="address" className="form-control" ref={register({required: true})} defaultValue={address} placeholder="Address" />
// {errors && errors.address && <span className="error">This Option is required</span>}
// </div>
// <div className="form-group">
// <button className="btn btn-danger">Save and Continue</button>
// </div>
// </form>
// </div>
// </div>
// </div>
);
};
export default Shipment;
Here is the error
TypeError: path.split is not a function
get
T:/1.Full-Stack-Developer/5.React/3.Red Onion/src/utils/get.ts:6
3 | import isUndefined from './isUndefined';
4 |
5 | export default (obj: any = {}, path: string, defaultValue?: unknown) => {
> 6 | const result = compact(path.split(/[,[\].]+?/)).reduce(
7 | (result, key) => (isNullOrUndefined(result) ? result : result[key]),
8 | obj,
9 | );
renderWithHooks
T:/1.Full-Stack-Developer/5.React/3.Red Onion/red-onion-resturant/node_modules/react-dom/cjs/react-dom.development.js:14985
29 | <form onSubmit={handleSubmit(onSubmit)} className="py-5">
30 |
31 | <div className="form-group">
> 32 | <input className="form-control" {...register( {requried: true})} defaultValue={todoor} placeholder="Delivery To Door"/>
| ^ 33 | {errors && errors.todoor && <span className="error">This Option is required</span>}
34 | </div>
35 | <div className="form-group">
The array.compact() method doesn't work and also you can't declare
the variable result and then pass it later as the accumulator.
Try writing it this way:
export default (obj: any = {}, path: string, defaultValue?: unknown) => {
return path.split(/[,[\].]+?/).reduce((result, key) => (
isNullOrUndefined(result) ? result : result[key]
), obj)
}

Categories

Resources