Why is my boolean statement always evaluating to true? - javascript

I'm pretty new to javascript, and I am trying to figure out how to calculate sales tax based off of US states. In my code, I attempted to use an if else statement based off of the input value of state to accomplish this. However, no matter what I put in for the value of state the tax is determined based off of 8.75%, and I'm not sure what I am doing wrong. I would really appreciate any help or advice on how to fix this problem.
Thank you
PlaceOrderScreen.js
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import { createOrder } from '../actions/orderActions';
import CheckoutSteps from '../components/CheckoutSteps';
import { ORDER_CREATE_RESET } from '../constants/orderConstants';
import LoadingBox from '../components/LoadingBox';
import MessageBox from '../components/MessageBox';
export default function PlaceOrderScreen(props) {
const cart = useSelector((state) => state.cart);
if (!cart.paymentMethod) {
props.history.push('/payment');
}
const orderCreate = useSelector((state) => state.orderCreate);
const { loading, success, error, order } = orderCreate;
const toPrice = (num) => Number(num.toFixed(2)); // 5.123 => "5.12" => 5.12
cart.itemsPrice = toPrice(
cart.cartItems.reduce((a, c) => a + c.qty * c.price, 0)
);
//Sales Tax//
{
if (cart.shippingAddress.state === 'New York'||'NY'){
cart.taxPrice = toPrice(0.0875 * cart.itemsPrice)}
else if (cart.shippingAddress.state === 'Kansas'||'KS') {
cart.taxPrice = toPrice(0.065 * cart.itemsPrice)}
else {
cart.taxPrice = toPrice(0 * cart.itemsPrice)}
};
cart.totalPrice = cart.itemsPrice + cart.shippingPrice + cart.taxPrice;
const dispatch = useDispatch();
const placeOrderHandler = () => {
dispatch(createOrder({ ...cart, orderItems: cart.cartItems }));
};
useEffect(() => {
if (success) {
props.history.push(`/order/${order._id}`);
dispatch({ type: ORDER_CREATE_RESET });
}
}, [dispatch, order, props.history, success]);
return (
<div>
<CheckoutSteps step1 step2 step3 step4></CheckoutSteps>
<div className="row top">
<div className="col-2">
<ul>
<li>
<div className="card card-body">
<h2>Shipping</h2>
<p>
<strong>Name:</strong> {cart.shippingAddress.fullName} <br />
<strong>Address: </strong> {cart.shippingAddress.address},
{cart.shippingAddress.city}, {cart.shippingAddress.state}, {cart.shippingAddress.postalCode}
,{cart.shippingAddress.country}
</p>
</div>
</li>
</ul>
</div>
</div>
</div>
ShippingAddressScreen.js
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { saveShippingAddress } from '../actions/cartActions';
import CheckoutSteps from '../components/CheckoutSteps';
export default function ShippingAddressScreen(props) {
const userSignin = useSelector((state) => state.userSignin);
const { userInfo } = userSignin;
const cart = useSelector((state) => state.cart);
const { shippingAddress } = cart;
if (!userInfo) {
props.history.push('/signin');
}
const [fullName, setFullName] = useState(shippingAddress.fullName);
const [address, setAddress] = useState(shippingAddress.address);
const [city, setCity] = useState(shippingAddress.city);
const [state, setState] = useState(shippingAddress.state);
const [postalCode, setPostalCode] = useState(shippingAddress.postalCode);
const [country, setCountry] = useState(shippingAddress.country);
const dispatch = useDispatch();
const submitHandler = (e) => {
e.preventDefault();
dispatch(
saveShippingAddress({ fullName, address, city, state, postalCode, country })
);
props.history.push('/payment');
};
return (
<div>
<CheckoutSteps step1 step2></CheckoutSteps>
<form className="form" onSubmit={submitHandler}>
<div>
<h1>Shipping Address</h1>
</div>
<div>
<label htmlFor="fullName">Full Name</label>
<input
type="text"
id="fullName"
placeholder="Enter full name"
value={fullName}
onChange={(e) => setFullName(e.target.value)}
required
></input>
</div>
<div>
<label htmlFor="address">Address</label>
<input
type="text"
id="address"
placeholder="Enter address"
value={address}
onChange={(e) => setAddress(e.target.value)}
required
></input>
</div>
<div>
<label htmlFor="city">City</label>
<input
type="text"
id="city"
placeholder="Enter city"
value={city}
onChange={(e) => setCity(e.target.value)}
required
></input>
</div>
<div>
<label htmlFor="state">State</label>
<input
type="text"
id="state"
placeholder="Enter state"
value={state}
onChange={(e) => setState(e.target.value)}
required
></input>
</div>
<div>
<label htmlFor="postalCode">Postal Code</label>
<input
type="text"
id="postalCode"
placeholder="Enter postal code"
value={postalCode}
onChange={(e) => setPostalCode(e.target.value)}
required
></input>
</div>
<div>
<label htmlFor="country">Country</label>
<input
type="text"
id="country"
placeholder="Enter country"
value={country}
onChange={(e) => setCountry(e.target.value)}
required
></input>
</div>
<div>
<label />
<button className="primary" type="submit">
Continue
</button>
</div>
</form>
</div>
);
}

Your code should look like this:
cart.shippingAddress.state === 'New York'|| cart.shippingAddress.state === 'NY'
Your current code is testing if the string "NY" is true or not, and that evaluates to true in your boolean test, so you're always getting the 8.75% tax rate.

Related

The table row cannot be deleted

I am new to react. I have difficulty deleting the table row. I find that the data variable in the member.js does not show the date that I input that I submitted. Why is that so? Can anyone find a solution why I can't delete the rows that I added.
My App.css
import dataMovielist from '../src/data/data.json';
import Members from './Members';
import AddMember from './AddMember';
import {useState} from 'react';
function App() {
const [datalist, setdatalist] = useState(dataMovielist);
const onSubmitHandler = ((newHobbies)=>{
setdatalist((oldHobbies)=>[newHobbies,...oldHobbies])
})
return (
<div className="App">
<AddMember onSubmitHandler = {onSubmitHandler} />
<Members data={datalist} onSubmitHandler = {onSubmitHandler}/>
</div>
);
}
export default App;
My Member.js
import React, { useState } from "react";
import '../src/css/movie.css'
import moviesdata from '../src/data/data.json';
function Members({ data, onSubmitHandler }) {
const [moviesData, setMoviesData] = useState(data);
console.log(moviesData)
const deleteMoviesHandler = (personIndex) => {
alert("hi")
console.log(moviesData)
moviesData.splice(personIndex, 1);
setMoviesData([...moviesData]);
};
const tableRows = (data) =>
data.map((info, num) => {
return (
<tr key={info.id} >
<td>{info.id}</td>
<td>{info.name}</td>
<td>
<img src={info["picture of image"]} alt=""></img>
</td>
<td>{info["lead actor"]}</td>
<td>{info.rating}</td>
<td><button onClick={()=>deleteMoviesHandler(num)}>Delete</button></td>
</tr>
);
});
return (
<div>
<table className="table table-stripped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Image</th>
<th>Actors</th>
<th>Rating</th>
</tr>
</thead>
<tbody>{tableRows(data)}</tbody>
</table>
</div>
);
}
export default Members;
My addMember.js
import React, { useState } from "react";
import "../src/css/addMember.css";
const AddMember = ({onSubmitHandler}) => {
const [idmovie,setidmovie] = useState("");
const [nameofmovie, setnameofmovie] = useState("");
const [moviepic, setmoviepic] = useState("");
const [leadActor, setleadActor] = useState("");
const [rating, setRating] = useState("");
function onChangeId(event){
setidmovie(event.target.value);
}
function onChangeName(event) {
setnameofmovie(event.target.value);
}
function onChangeImage(event) {
setmoviepic(event.target.value);
}
function onChangeActor(event) {
setleadActor(event.target.value.split(","));
}
function onChangeRating(event) {
setRating(event.target.value);
}
const transferValue = (event) => {
event.preventDefault();
const val = {
id : idmovie,
name: nameofmovie,
"picture of image": moviepic,
"lead actor": leadActor,
rating: rating,
};
onSubmitHandler(val);
clearState();
};
const clearState = () => {
setidmovie("");
setnameofmovie("");
setmoviepic("");
setleadActor("");
setRating("");
};
return (
<div>
<div id="topFormLayerOne">
<form>
<div id="secondFormLayerTwo">
<label id="labelTwo">Please key in the Id</label>
<input
id="inputThree"
type="text"
maxLength="10"
onChange={onChangeId}
placeholder="Please key in the Id"
></input>
<label id="labelFour">Movie Names</label>
<input
onChange={onChangeName}
id="inputFour"
type="text"
maxLength="100"
placeholder="Movies Names"
name="moviesName"
></input>
<label id="labelFive">Picture of Movies</label>
<input
onChange={onChangeImage}
id="inputFive"
type="file"
maxLength="100"
placeholder="Name of Images"
name="imageName"
></input>
<label id="labelSix">Lead Actor Names</label>
<input
onChange={onChangeActor}
id="inputSix"
type="text"
maxLength="500"
placeholder="Name of Actor"
name="actorName"
></input>
<label id="labelSeven">Rating</label>
<input
onChange={onChangeRating}
id="inputSeven"
type="text"
maxLength="10"
placeholder="Rating"
name="movieRating"
></input>
<button onClick={transferValue} id="submitButton">
Submit
</button>
<button id="removeButton">Remove Movie</button>
</div>
</form>
</div>
</div>
);
};
export default AddMember;
My data.json
[{ "id": 1,"name" : "Ticket to Paradise","picture of image":"../images/Ticket_to_Paradise.jpg", "lead actor": ["George Clooney", "Julia Roberts"],"rating":5}]
Can you help me solve theis problems?
Problem
Your deleteMoviesHandler deletes items from their local state of Members and what is rendered is the parent state.
Solution
You don't need to keep another state inside the Members component.
Move the deleteMoviesHandler to the parent component and pass it down to Members.
function App() {
...
...
const deleteMoviesHandler = (personIndex) => {
datalist.splice(personIndex, 1);
setdatalist([...datalist]);
};
...
...
<Members
...
...
deleteMoviesHandler={deleteMoviesHandler}
/>
Use it from Members component.
function Members({ data, onSubmitHandler, deleteMoviesHandler }) {...}
Working Demo:

How to pass multiple onChange form data from child to parent element in react

I am trying to print real-time user input from input tags by the user. I am even getting multiple user inputs from the child element to the parent element as a form of an object using useState. But whenever the user tries to fill the second input field, then the first input is re-render and it's replaced by the primary state which is an empty string.
code:-
Child Element
import React, { useState } from "react";
const Child = (props) => {
const [name, setName] = useState("");
const [age, setAge] = useState("");
let userData = {
name: "",
age: ""
};
const nameChangeHandler = (e) => {
setName(e.target.value);
userData.name = e.target.value;
};
const ageChangeHandler = (e) => {
setAge(e.target.value);
userData.age = e.target.value;
};
const formOnChageHandler = (e) => {
e.preventDefault();
props.getData(userData);
};
const fromOnSubmitHandler = (e) => {
e.preventDefault();
};
return (
<React.Fragment>
<form onChange={formOnChageHandler} onSubmit={fromOnSubmitHandler}>
<label htmlFor="name">Name:</label>
<input
id="name"
placeholder="Enter Name"
value={name}
onChange={nameChangeHandler}
/>
<br />
<label htmlFor="age">Age:</label>
<input
id="age"
placeholder="Enter Age"
value={age}
onChange={ageChangeHandler}
/>
</form>
</React.Fragment>
);
};
export default Child;
Parent Element
import React, { useState } from "react";
import Child from "./components/Child";
function App() {
const [name, setName] = useState("");
const [age, setAge] = useState("");
let userData = (data) => {
setName(data.name);
setAge(data.age);
};
return (
<React.Fragment>
<Child getData={userData} />
<h1>Your name is:{name}</h1>
<h1>Your age is:{age}</h1>
</React.Fragment>
);
}
export default App;
code sandbox Link- https://codesandbox.io/s/from-traversing-child-to-parent-to-another-child-ynwyqd?file=/src/App.js:0-441
How I can get both data being reflected by using onChange from child to parent element?
I suggest you accumulate the user data in one state.
Like this.
const [user, setUser] = useState({
name: "",
age: null
});
And put the state on the parent and pass as props, also just have one handleChange function to update both the name and age by the input id
Child.js
import React, { useState } from "react";
const Child = ({ user, setUser }) => {
const handleChange = (e) => {
setUser((prev) => ({
...prev,
[e.target.id]: e.target.value
}));
};
const formOnChageHandler = (e) => {
e.preventDefault();
};
const fromOnSubmitHandler = (e) => {
e.preventDefault();
};
return (
<React.Fragment>
<form onChange={formOnChageHandler} onSubmit={fromOnSubmitHandler}>
<label htmlFor="name">Name:</label>
<input
id="name"
placeholder="Enter Name"
value={user.name}
onChange={handleChange}
/>
<br />
<label htmlFor="age">Age:</label>
<input
id="age"
placeholder="Enter Age"
value={user.age}
onChange={handleChange}
/>
</form>
</React.Fragment>
);
};
export default Child;
App.js
import React, { useState } from "react";
import Child from "./components/Child";
function App() {
const [user, setUser] = useState({
name: "",
age: null
});
return (
<React.Fragment>
<Child user={user} setUser={setUser} />
<h1>Your name is:{user.name}</h1>
<h1>Your age is:{user.age}</h1>
</React.Fragment>
);
}
export default App;
CODESANDBOX
Try using the child component as below,
import React, { useState } from "react";
const Child = (props) => {
const [name, setName] = useState("");
const [age, setAge] = useState("");
let userData = {
name: name, // the value "name" comes for the local state will be listen to the onChange event every time
age: age // same applies here as well
};
const nameChangeHandler = (e) => {
setName(e.target.value);
};
const ageChangeHandler = (e) => {
setAge(e.target.value);
};
const formOnChageHandler = (e) => {
e.preventDefault();
props.getData(userData);
};
const fromOnSubmitHandler = (e) => {
e.preventDefault();
};
return (
<React.Fragment>
<form onSubmit={fromOnSubmitHandler}>
<label htmlFor="name">Name:</label>
<input
id="name"
placeholder="Enter Name"
value={name}
onChange={nameChangeHandler}
/>
<br />
<label htmlFor="age">Age:</label>
<input
id="age"
placeholder="Enter Age"
value={age}
onChange={ageChangeHandler}
/>
</form>
</React.Fragment>
);
};
export default Child;
just use simple one state to manage data. just take a look below example component created from your child component.
we simply use single object state.
use name prop as key to store value in state.
import React, { useState } from "react";
const Child = (props) => {
const [formData, setFormData] = useState({});
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setFormData({
...formData,
[e.target.name]: e.target.value,
});
};
const formOnChageHandler = (e) => {
e.preventDefault();
props.getData(userData);
};
const fromOnSubmitHandler = (e) => {
e.preventDefault();
};
return (
<React.Fragment>
<form onChange={formOnChageHandler} onSubmit={fromOnSubmitHandler}>
<label htmlFor="name">Name:</label>
<input
id="name"
placeholder="Enter Name"
value={name}
onChange={handleChange}
name="name"
/>
<br />
<label htmlFor="age">Age:</label>
<input
id="age"
placeholder="Enter Age"
value={age}
onChange={handleChange}
name="age"
/>
</form>
</React.Fragment>
);
};
export default Child;
<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>
it happens because you dont watch to the state, try this:
Child.js
import React, { useState } from "react";
const Child = (props) => {
const [name, setName] = useState("");
const [age, setAge] = useState("");
let userData = {
name,
age
};
const nameChangeHandler = (e) => {
setName(e.target.value);
userData.name = e.target.value;
};
const ageChangeHandler = (e) => {
setAge(e.target.value);
userData.age = e.target.value;
};
const formOnChageHandler = (e) => {
e.preventDefault();
props.getData(userData);
};
const fromOnSubmitHandler = (e) => {
e.preventDefault();
};
return (
<React.Fragment>
<form onChange={formOnChageHandler} onSubmit={fromOnSubmitHandler}>
<label htmlFor="name">Name:</label>
<input
id="name"
placeholder="Enter Name"
value={name}
onChange={nameChangeHandler}
/>
<br />
<label htmlFor="age">Age:</label>
<input
id="age"
placeholder="Enter Age"
value={age}
onChange={ageChangeHandler}
/>
</form>
</React.Fragment>
);
};
export default Child;
Try this, i check in codesandbox and it works:
In App.js:
import React, { useState } from "react";
import Child from "./components/Child";
function App() {
const [name, setName] = useState("");
const [age, setAge] = useState("");
return (
<React.Fragment>
<Child name={name} age={age} setName={setName} setAge={setAge} />
<h1>Your name is:{name}</h1>
<h1>Your age is:{age}</h1>
</React.Fragment>
);
}
export default App;
In Child.js:
import React, { useState } from "react";
const Child = ({ name, age, setName, setAge }) => {
const nameChangeHandler = (e) => {
setName(e.target.value);
};
const ageChangeHandler = (e) => {
setAge(e.target.value);
};
const fromOnSubmitHandler = (e) => {
e.preventDefault();
};
return (
<React.Fragment>
<form onSubmit={fromOnSubmitHandler}>
<label htmlFor="name">Name:</label>
<input
id="name"
placeholder="Enter Name"
value={name}
onChange={nameChangeHandler}
/>
<br />
<label htmlFor="age">Age:</label>
<input
id="age"
placeholder="Enter Age"
value={age}
onChange={ageChangeHandler}
/>
</form>
</React.Fragment>
);
};
export default Child;
If you want to improve your code, you can research and use state management like: redux, zustand, react context,...
Hope it useful for you.

How to display User name in profile page - react / firebase

I have made a signup/login/logout page which works perfectly fine, however I wanted to add an additional field in the register page for user name, and I wanted the username to display in the profile page.
I was able to inset the username field into the register page, and I have a name section on the profile page which also shows up when the profile page loads, however, when I input a user name in the register page, it does not appear in the profile page.
Can anyone please help me figure this out? I really appreciate the help everyone. My first post here :) just recently started my developer journey
// register.js
import { useState } from "react";
import "./forms.css";
import { auth } from "./firebase";
import { useNavigate, Link } from "react-router-dom";
import {
createUserWithEmailAndPassword,
sendEmailVerification,
} from "firebase/auth";
import { useAuthValue } from "./AuthContext";
function Register() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [error, setError] = useState("");
const navigate = useNavigate();
const { setTimeActive } = useAuthValue();
const validatePassword = () => {
let isValid = true;
if (password !== "" && confirmPassword !== "") {
if (password !== confirmPassword) {
isValid = false;
setError("Passwords does not match");
}
}
return isValid;
};
const register = (e) => {
e.preventDefault();
setError("");
if (validatePassword()) {
// Create a new user with email and password using firebase
createUserWithEmailAndPassword(auth, email, password)
.then(() => {
sendEmailVerification(auth.currentUser)
.then(() => {
setTimeActive(true);
navigate("/verify-email");
})
.catch((err) => alert(err.message));
})
.catch((err) => setError(err.message));
}
setName("");
setEmail("");
setPassword("");
setConfirmPassword("");
};
return (
<div className="center">
<div className="auth">
<h1>Register Account</h1>
{error && <div className="auth__error">{error}</div>}
<form onSubmit={register} name="registration_form">
<input
type="name"
value={name}
placeholder="Enter your user name"
required
onChange={(e) => setName(e.target.value)}
/>
<input
type="email"
value={email}
placeholder="Enter your email"
required
onChange={(e) => setEmail(e.target.value)}
/>
<input
type="password"
value={password}
required
placeholder="Enter your password"
onChange={(e) => setPassword(e.target.value)}
/>
<input
type="password"
value={confirmPassword}
required
placeholder="Confirm password"
onChange={(e) => setConfirmPassword(e.target.value)}
/>
<button type="submit">Register</button>
</form>
<span>
Already have an account?
<Link to="/login">login</Link>
</span>
</div>
</div>
);
}
export default Register;
import "./profile.css";
import { useAuthValue } from "./AuthContext";
import { signOut } from "firebase/auth";
import { auth } from "./firebase";
function Profile() {
const { currentUser } = useAuthValue();
return (
<div className="center">
<div className="profile">
<h1>Profile</h1>
<p>
<strong>Name: </strong>
{currentUser?.name}
</p>
<p>
<strong>Email: </strong>
{currentUser?.email}
</p>
<p>
<strong>Email verified: </strong>
{`${currentUser?.emailVerified}`}
</p>
<span onClick={() => signOut(auth)}>Sign Out</span>
</div>
</div>
);
}
export default Profile;

where to call the Axios post request in reactjs

I have a form,thats data are saved in the state to be sent to the backend server.
i am handling the form with handleSubmit function and useEffect hook, where the handleSubmit prevents the form from being submitted unless it calls the validation function, in the useEffect I check if there are any errors using if condition and then console.log my data.
now I want to post the data hold in the state -the state is sent as a props to me- but I am confused whether to put the request in the HandleSubmit function or in the useEffect inside the body of the if condition.
import react, { Component, useState, useEffect } from 'react';
import {useNavigate } from 'react-router-dom';
import axios from 'axios';
import './sign.css';
const SignA = (props) => {
const navigate = useNavigate();
const [formErrors, setFormErrors] = useState({});
const [isSubmit, setIsSubmit] = useState(false);
const handleSubmit = (err) => {
err.preventDefault();
setFormErrors(validate(props.data));
setIsSubmit(true);
}
useEffect(() => {
console.log(Object.keys(formErrors).length);
if (Object.keys(formErrors).length === 0 && isSubmit) {
console.log('console the props data', props.data)
//here is where I think the post request should be put
if (isSubmit) {
return (navigate('/profileadmin'))
}
}
}, [formErrors])
const validate = (values) => {
const errors = {};
const regex = /^[^\s#]+#[^\s#]+\.[^\s#]{2,}$/i;
if (!values.firstname) {
errors.firstname = 'firstname is required!';
}
if (!values.lastname) {
errors.lastname = 'lastname is required!';
}
if (!values.mobile) {
errors.mobile = 'mobile is required!';
}
if (!values.email) {
errors.email = 'email is required!';
} else if (!regex.test(values.email)) {
errors.email = 'this is not a valid email format!'
}
return errors;
}
return (
<div className='signup'>
<form onSubmit={handleSubmit} >
<div className="container">
<h1>Sign Up</h1>
<div className="name">
<div>
<input
type="text"
placeholder="First name"
name="firstname"
id='firstName'
value={props.data.firstname}
onChange={props.change}
/>
</div>
<div>
<input
type="text"
placeholder="Last name"
name="lastname"
value={props.data.lastname}
onChange={props.change}
/>
</div>
</div>
<p className='errorMsg'>{formErrors.firstname}</p>
<p className='errorMsg'>{formErrors.lastname}</p>
<br />
<div>
<input
type="text"
placeholder="Business mobile number"
name="mobile"
value={props.data.mobile}
onChange={props.change}
/>
<p className='errorMsg'>{formErrors.mobile}</p>
<br />
<input
type="text"
placeholder="Email Adress"
name="email"
value={props.data.email}
onChange={props.change}
/>
<p className='errorMsg'>{formErrors.email}</p>
<br />
</div>
</div>
<br />
<div className="checkbox">
<label>
<input type="checkbox" className="check" />i’ve read and agree with <a href="url" >Terms of service</a>
</label>
</div>
<div className="clearfix">
<button type="submit" className="signupbtn">Sign Up</button>
</div>
</div>
</form >
</div >
)
}
export default SignA;
this is the request
axios.post('', props.data)
.then(res => console.log('post res', res))
.catch(error => {
console.error('There was an error in post request!', error);
});
You don't necessarily need useEffect here.
Here is how you can implement such thing:
Declare a state to hold form values:
const [formData, setFormData] = useState({})
Declare function to set the state:
const handleChange = (name, value) => {
setFormData({...formData, [name]: value})
}
Input onChange to capture:
// handleChange has two parameters
<input
type="text"
placeholder="First name"
name="firstname"
id='firstName'
value={props.data.firstname}
onChange={(event) => handleChange('firstName', event.target.value)}
/>
function for calling post axios post request
const handleSubmit = () => {
//check for validations code here
// if validations are right then post request here
// this will give you all the fields like firstName: "", lastName: ""
let requestBody = {
...formData
}
axios.post("url", requestBody).then((res)=> {
//your code here
})
}

ReactJS: Unhandled Rejection (TypeError): Cannot read property 'push' of undefined. Having issues pushing to another component

App not behaving correctly when I try signing up along with posting Stripe payment, it will not push the sashboard component
The error I am getting:
Unhandled Rejection (TypeError): Cannot read property 'push' of undefined
handleStripeSubmit
src/components/sections/SignupForm.js:78
75 | const { id } = paymentMethod;
76 | console.log("111111111 and ID_", id);
77 | aprops.signup(state, id);
78 | aprops.history.push("/dashboard");
| ^ 79 |
80 | console.log("3333333333");
81 | // setState({ ...state, stripeId: id });
My Code (what do youthink is not working?:
someone, please help...
import React, { useState } from "react";
import classNames from "classnames";
import { Link, withRouter, Route } from "react-router-dom";
import SectionHeader from "./partials/SectionHeader";
import Input from "../elements/Input";
import Button from "../elements/Button";
import { signupUser } from "../../redux/actions/user_action";
import { CardElement, useStripe, useElements } from "#stripe/react-stripe-js";
import { connect } from "react-redux";
import { createHashHistory } from 'history';
export const history = createHashHistory()
//Checkout Form component-----------------------------------------------=
const StripeForm = (aprops) => {
const [state, setState] = useState({
bname: "Busines Name",
email: "Email address",
password: "Password",
name: "Name on Card",
amount: 0,
plan: "",
stripeId: "",
});
const {
className,
topOuterDivider,
bottomOuterDivider,
topDivider,
bottomDivider,
hasBgColor,
invertColor,
...props
} = aprops;
const outerClasses = classNames(
"signin section",
topOuterDivider && "has-top-divider",
bottomOuterDivider && "has-bottom-divider",
hasBgColor && "has-bg-color",
invertColor && "invert-color",
className
);
const innerClasses = classNames(
"signin-inner section-inner",
topDivider && "has-top-divider",
bottomDivider && "has-bottom-divider"
);
const sectionHeader = {
title: "Welcome. We exist to make cybersecurity easier.",
};
const handlechangeall = (event) => {
setState({ ...state, [event.target.name]: event.target.value });
};
const handleRadio = (e) => {
setState({
...state,
amount: Number(e.target.value) * 100,
plan: e.target.id,
});
};
const handleStripeSubmit = async () => {
const { error, paymentMethod } = await stripe.createPaymentMethod({
type: "card",
card: elements.getElement(CardElement),
});
if (!error) {
console.log("response of stripe payment___", paymentMethod);
const { id } = paymentMethod;
console.log("111111111 and ID_", id);
aprops.signup(state, id);
aprops.history.push("/dashboard");
console.log("3333333333");
// setState({ ...state, stripeId: id });
}
};
const handlesubmit = (event) => {
event.preventDefault();
handleStripeSubmit();
//alert( JSON.stringify(this.state));
console.log(JSON.stringify(state));
};
//Stripe hooks-------
const stripe = useStripe();
const elements = useElements();
//=============================
return (
<section {...aprops} className={outerClasses}>
<div className="container">
<div className={innerClasses}>
<SectionHeader
tag="h1"
data={sectionHeader}
className="center-content"
/>
<div className="tiles-wrap">
<div className="tiles-item">
<div className="tiles-item-inner">
<form onSubmit={handlesubmit}>
<fieldset>
<div className="mb-12">
<Input
label="Business name"
type="text"
name="bname"
value={state.bname}
onChange={handlechangeall}
labelHidden
required
/>
</div>
<div className="mb-12">
<Input
type="email"
name="email"
label="Email"
value={state.email}
onChange={handlechangeall}
labelHidden
required
/>
</div>
<div className="mb-12">
<Input
type="password"
name="password"
label="Password"
value={state.password}
onChange={handlechangeall}
labelHidden
required
/>
</div>
{/* Stripe Integration */}
<div className="signin-bottom has-top-divider">
<div className="pt-32 text-xs center-content text-color-low">
Select Subscription tier (to select, use up & down arrow
keys):
</div>
</div>
{/* all packages amounts here */}
<div onChange={handleRadio} className="radio">
{console.log("checking plan amount____", state.amount)}
<div>
<label>
<input
type="radio"
id="default"
value="49"
name="plan"
/>
($49/month)
</label>
</div>
<div>
<label>
<input
type="radio"
id="basic"
name="plan"
value="199"
/>
Basic ($199/month)
</label>
</div>
<div>
<label>
<input
type="radio"
id="complete"
name="plan"
value="249"
/>
Complete ($249/month)
</label>
</div>
</div>
<div className="pt-32 text-xs center-content text-color-low">
Enter Card Details Here!
<div className="mb-12">
<Input
label="Name on the card"
type="text"
name="name"
value={state.name}
onChange={handlechangeall}
labelHidden
required
/>
</div>
<div
style={{
border: "1px solid grey",
padding: 15,
backgroundColor: "#cccccc",
}}
>
<CardElement />
</div>
{/* <button type="submit" disabled={!stripe}>
Checkout
</button> */}
<div className="mt-24 mb-32">
<Button type="submit" color="primary" wide>
Register
</Button>
</div>
</div>
</fieldset>
</form>
<div className="signin-bottom has-top-divider">
<div className="pt-32 text-xs center-content text-color-low">
Already have an account?{" "}
<Link to="/login/" className="func-link">
Login
</Link>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
);
};
// const SignupForm = () => {
// return (
// <Elements stripe={stripePromise}>
// <StripeForm />
// </Elements>
// );
// };
// SignupForm.propTypes = propTypes;
// SignupForm.defaultProps = defaultProps;
const mapStateToProps = (state) => ({});
const mapDispatchToProps = (dispatch) => {
return { signup: (data, id) => dispatch(signupUser(data, id)) };
};
export default connect(mapStateToProps, mapDispatchToProps)(StripeForm);
You are not passing history prop to StripeForm component - it is undefined. what is actually passed is { signup: (data, id) => dispatch(signupUser(data, id)) }.
A possible solution could be:
const mapStateToProps = (state) => ({ history: [] });
or assigning history some default value:
const {
className,
topOuterDivider,
bottomOuterDivider,
topDivider,
bottomDivider,
hasBgColor,
invertColor,
history = [],
...props
} = aprops;

Categories

Resources