where to call the Axios post request in reactjs - javascript

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

Related

onValidated is not a function when trying to subscribe user to mailchimp

I am using "react-mailchimp-subscribe" to integrate with MailChimp and enable users to signup to a mailchimp mailing list upon completing an submitting my form.
However, I get the error:
Uncaught TypeError: onValidated is not a function
When I trigger the function that should submit the form info to MailChimp.
Here is a sample of my code:
import MailchimpSubscribe from "react-mailchimp-subscribe";
...
const CustomForm = ({
className,
topOuterDivider,
bottomOuterDivider,
topDivider,
bottomDivider,
hasBgColor,
invertColor,
split,
status,
message,
onValidated,
...props
}) => {
...
const [email, setEmail] = useState('');
const [fullName, setFullName] = useState('');
const handleSubmit = (e) => {
console.log('handlesubmit triggered')
e.preventDefault();
email &&
fullName &&
email.indexOf("#") > -1 &&
onValidated({
EMAIL: email,
MERGE1: fullName,
});
}
...
<form onSubmit={(e) => handleSubmit(e)}>
<h3>
{status === "success"
? "You have successfully joined the mailing list"
: "Join our mailing list by completing the form below"
}
</h3>
<div className="cta-action">
<Input
id="email"
type="email"
label="Subscribe"
labelHidden hasIcon="right"
placeholder="Your email address"
onChange={e => setEmail(e.target.value)}
value={email}
isRequired
>
</Input>
<Input
id="name"
type="text"
label="Subscribe"
labelHidden hasIcon="right"
placeholder="Your full name"
onChange={e => setFullName(e.target.value)}
value={fullName}
isRequired
>
</Input>
<Input
type="submit"
formValues={[email, fullName]}
/>
</div>
</form>
This is the parent component passing down props to the above:
import React from "react";
import MailchimpSubscribe from "react-mailchimp-subscribe";
const MailchimpFormContainer = props => {
const postURL = `https://*li$%.list-manage.com/subscribe/post?u=${process.env.REACT_APP_MAILCHIMP_U}$id=${process.env.REACT_APP_MAILCHIMP_ID}`;
return (
<div>
<MailchimpSubscribe
url={postURL}
render={({ subscribe, status, message }) => (
<CustomForm
status={status}
message={message}
onValidated={ formData => subscribe(formData) }
/>
)}
/>
</div>
);
};

While implementing react-intl-tel-input in my react JS it give me errors

Hello I have started learning ReactJS and from last 1 week i stuck with a problem. I am using React with Firebase Phone Authentication. I want to use react-intl-tel-input for taking Phone input. I have installed the npm package and write the code as told in documentation. after running the code it takes the input correctly but after clicking on verify it say this number is not register but this number work perfectly with tag but not with this
please have a look on my code
import React from 'react'
import firebase from './firebase'
import 'firebase/auth';
import "./App.css";
import { getDatabase, ref, child, get } from "firebase/database";
import IntlTelInput from 'react-intl-tel-input';
import 'react-intl-tel-input/dist/main.css';
class Login extends React.Component {
state = {};
handlePhoneChange = (status, phoneNumber, country) => {
console.log({ phoneNumber });
this.setState({ phoneNumber });
};
handleChange = (e) => {
console.log (e)
const { name, value } = e.target
this.setState({
[name]: value
})
console.log (value)
this.setState({ phoneNumber: value }, () => {
console.log(this.state.phoneNumber);
});
}
configureCaptcha = () =>{
window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
'size': 'invisible',
'callback': (response) => {
// reCAPTCHA solved, allow signInWithPhoneNumber.
this.onSignInSubmit();
console.log("Recaptca varified")
},
// defaultCountry: "IN"
}
);
}
onSignInSubmit = (e) => {
e.preventDefault()
this.configureCaptcha()
const phoneNumber = this.state.mobile
console.log(phoneNumber)
const appVerifier = window.recaptchaVerifier;
const dbRef = ref(getDatabase());
get(child(dbRef, `Users/${phoneNumber}`)).then((snapshot) => {
if (snapshot.exists()) {
firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
.then((confirmationResult) => {
window.confirmationResult = confirmationResult;
alert('An OTP has been sent to your registered mobile number')
localStorage.setItem("Phone_No", phoneNumber)
console.log(localStorage.getItem('Phone_No'));
}).catch((error) => {
console.error(error);
alert("Oops! Some error occured. Please try again.")
});
}
else {
alert('Sorry, this mobile number is not registered with us. Please use your registered mobile number.');
}
})
}
onSubmitOTP = (e) => {
e.preventDefault()
const code = this.state.otp
console.log(code)
window.confirmationResult.confirm(code).then((result) => {
// User signed in successfully.
const Users = result.user;
console.log(JSON.stringify(Users))
this.props.history.push("/home");
}).catch((error) => {
alert("You have entered wrong code")
});
}
render() {
return (
<>
<main>
<div className="img">
<img src="./55k-logo.png" alt="Company Logo" style={{ height: "80px", width: "200px" }} />
<br />
</div>
<fieldset>
<div className="Main-header">
<h1>Sign-In</h1>
<p>Limtless Water. From Unlimited Air.</p>
<form onSubmit={this.onSignInSubmit}>
<div id="sign-in-button"></div>
<label>Mobile Number</label> <br />
<IntlTelInput
containerClassName="intl-tel-input"
inputClassName="form-control"
name="mobile"
placeholder="Enter Your Number"
input
type="tel"
value={this.state.phoneNumber}
onPhoneNumberChange={this.handlePhoneChange}
/>
{/* <input type="tel" id="phone" name="mobile" placeholder="Enter Your Number" required onChange={this.handleChange} /> */}
<div className="buttons">
<button type="submit">Verify</button>
</div>
</form>
<div>
<form onSubmit={this.onSubmitOTP}>
<label >Code</label> <br />
<input type="text" name="otp" placeholder="Enter six digit code" required onChange={this.handleChange} />
<div className="buttons" >
<button type="submit">Continue</button>
</div>
</form>
</div>
</div>
</fieldset>
</main>
</>
)
}
}
export default Login;
after running the code i got this message but my number is registered
But my code work perfectly with this
<input type="tel" id="phone" name="mobile" placeholder="Enter Your Number" required onChange={this.handleChange} /> but i don't want to take input with normal input tag because here user have to type country code manually

How to integrate react-intl-tel-input-v2

While using react-intl-tel-input-v2 I was getting this error:-× TypeError: Cannot read properties of null (reading 'e') I have install the react-intl-tel-input-v2 from npm Try many things but nothing work if anyone know the solution please help Even if you know any other npm package which help me please suggest
I was getting the error in this part:-
handleChange = (e) => { const { name, value } = e.target this.setState({ [name]: value
This is my code
import React from 'react'
import firebase from './firebase'
import 'firebase/auth';
import "./App.css";
import { getDatabase, ref, child, get } from "firebase/database";
// import PhoneInput from 'react-phone-number-input'
// import $ from 'jquery';
// import intlTelInputUtils from 'jquery';
import ReactIntlTelInput from 'react-intl-tel-input-v2';
import 'intl-tel-input/build/css/intlTelInput.css';
class Login extends React.Component {
handleChange = (e) => {
const { name, value } = e.target
this.setState({
[name]: value
})
this.setState({ phoneNumber: value }, () => {
console.log(this.state.phoneNumber);
});
}
configureCaptcha = () =>{
window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
'size': 'invisible',
'callback': (response) => {
// reCAPTCHA solved, allow signInWithPhoneNumber.
this.onSignInSubmit();
console.log("Recaptca varified")
},
defaultCountry: "IN"
}
);
}
onSignInSubmit = (e) => {
e.preventDefault()
this.configureCaptcha()
const phoneNumber = this.state.mobile
console.log(phoneNumber)
const appVerifier = window.recaptchaVerifier;
const dbRef = ref(getDatabase());
get(child(dbRef, `Users/${phoneNumber}`)).then((snapshot) => {
if (snapshot.exists()) {
firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
.then((confirmationResult) => {
// SMS sent. Prompt user to type the code from the message, then sign the
// user in with confirmationResult.confirm(code).
window.confirmationResult = confirmationResult;
alert('An OTP has been sent to your registered mobile number')
localStorage.setItem("Phone_No", phoneNumber)
console.log(localStorage.getItem('Phone_No'));
}).catch((error) => {
console.error(error);
alert("Oops! Some error occured. Please try again.")
});
}
else {
alert('Sorry, this mobile number is not registered with us. Please use your registered mobile number.');
}
})
}
onSubmitOTP = (e) => {
e.preventDefault()
const code = this.state.otp
console.log(code)
window.confirmationResult.confirm(code).then((result) => {
// User signed in successfully.
const Users = result.user;
console.log(JSON.stringify(Users))
this.props.history.push("/home");
}).catch((error) => {
alert("You have entered wrong code")
});
}
render() {
return (
<div className="Main-header">
<img src="./55k-logo.png" alt="Company Logo" style={{ height: "80px", width: "200px" }} />
<br />
<div>
<h2>Login Form</h2>
<p>Limtless Water. From Unlimited Air.</p>
<form onSubmit={this.onSignInSubmit}>
<div id="sign-in-button"></div>
{/* <PhoneInput */}
<label>Mobile Number</label> <br />
{/* for="phoneNumber" */}
<ReactIntlTelInput
type="tel" id="phone" name="mobile" placeholder="Enter Your Number" required onChange={this.handleChange}
value={this.state.value}
// onChange={this.handleChange}
/>
{/* <input type="tel" id="phone" name="mobile" placeholder="Enter Your Number" required onChange={this.handleChange} /> */}
<div className="buttons">
<button type="submit">Submit</button>
</div>
</form>
</div>
<div>
<form onSubmit={this.onSubmitOTP}>
<label >Code</label> <br />
{/* for="code" */}
<input type="number" name="otp" placeholder="Enter The 6 Digit OTP" required onChange={this.handleChange} />
<div className="buttons" >
<button type="submit">Submit</button>
</div>
</form>
</div>
</div>
)
}
}
export default Login;

Why is my boolean statement always evaluating to true?

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.

Prevent to send form if there is an error

A sandbox with my components : https://codesandbox.io/s/fancy-star-7gite
Hello, I've tried to code in React.js a contact form which check if values of inputs are good and send it to a mailbox via email.js. Sample of the validation's file(validateInfo.jsx):
if(!values.email) {
errors.email= "Enter an e-mail";
} else if (!/\S+#\S+\.\S+/.test(values.email)){
errors.email= "Enter a valid email";
}
But at the submission of the form even if the values are wrong, it sends the form. I want to prevent it.
To transport the form to a mailbox I've created a hook to manage the sending of the information in the form (useContact.jsx):
import {useState, useEffect} from 'react'
import emailjs from "emailjs-com";
import {template} from "./template";
import {userId} from "./userid";
export const useContact = (callback, validate) => {
const [values, setValues] = useState({
email:'',
emailConf:'',
userName:'',
phone:'',
})
const [errors, setErrors] = useState({})
const [isSubmitting, setIsSubmitting] = useState(false)
const handleChange = e =>{
const {name, value}= e.target
setValues({
...values,
[name]: value
})
}
function handleSubmit(e) {
e.preventDefault()
setIsSubmitting(true)
setErrors(validate(values))
emailjs.sendForm('gmail', template, e.target, userId)
.then((result) => {
console.log(result)
}, (errors) => {
console.log(errors);
});
e.target.reset();
localStorage.clear();
}
useEffect(() =>{
if(Object.keys(errors).length === 0 && isSubmitting)
{
callback();
}
},[errors])
return {handleChange, handleSubmit, values, errors};
}
The form (ContactInfo.jsx):
import './Contact.css';
import { useContact } from "./useContact";
import validate from './validateInfo';
export default function ContactInfo({submitForm}) {
const {handleChange, values, handleSubmit, errors}
= useContact(
submitForm,
validate
)
return (<>
<div className="contact-container">
<div className="contactForm" >
<form className="Contact" onSubmit={handleSubmit} >
<input
id="email"
name="email"
type="email"
value={values.email}
onChange={handleChange}
className="form-input"
placeholder="E-mail"
minLength= '5'
maxLength ='50'
autoComplete="off"/>
{errors.email && <p> {errors.email} </p>}
<input
name="emailConf"
id="emailConf"
type="email"
value={values.emailConf}
onChange={handleChange}
className="form-input"
minLength= '5'
maxLength='50'
autoComplete="off"
placeholder="E-mail confirmation"/>
{errors.emailConf && <p> {errors.emailConf} </p>}
<input
name="userName"
id="userName"
value={values.userName}
onChange={handleChange}
className="form-input"
maxLength='50'
autoComplete="off"
placeholder="Name"/>
<input
name="phone"
id="phone"
type="tel"
value={values.phone}
onChange={handleChange}
className="form-input"
maxLength='10'
autoComplete="off"
placeholder="Phone Number"/>
{errors.phone && <p> {errors.phone} </p>}
<textarea
className="message"
name="message"
maxLength='500'
placeholder="Write your message here..." />
<button className="submit-Btn" type="submit">
Send
</button>
</form>
</div>
</div>
</>
);
}
Thank you for helping me if you want more informations tell me =).
You are missing a condition in submit method. You are not validating whether there is any error in validation. It should be as follows. Updated the codesandbox as well
function handleSubmit(e) {
e.preventDefault();
setIsSubmitting(true);
setErrors(validate(values));
if (validate(values) === {}) {
emailjs.sendForm("gmail", template, e.target, userId).then(
(result) => {
console.log(result);
},
(errors) => {
console.log(errors);
}
);
e.target.reset();
localStorage.clear();
}
}

Categories

Resources