How to find display error message from API in reactjs - reactjs

I'm new to React.JS, creating an app for contacts. From API, the fields of contact got validated, if same name or phone number exists then it will show error message in API. My query is how to show the error message in UI while entering the same name or phone number. Do I need to fetch from Contact API? If yes, I could fetch the API of contacts in DIdmount but don't know how to show the error? Can any one help me in this?

Create a state variable for error with the initial value set to "" or null. Make the api call, the server (assuming you are also building the server) should check to see if the name and phone number already exist. If they already exist the server should return an error. In your react app catch the error after your API call and assign it to your state variable for error. Here is an example for the client using hooks.
export default function RegistrationForm(props) {
const [error, setError] = useState(null)
const errorDiv = error
? <div className="error">
<i class="material-icons error-icon">error_outline</i>
{error}
</div>
: '';
const handleSubmit = e => {
e.preventDefault();
setError(null);
const { full_name, user_name, password } = e.target;
AuthApiService.postUser({
full_name: full_name.value,
user_name: user_name.value,
password: password.value
})
.then(user => {
full_name.value = '';
user_name.value = '';
password.value = '';
props.onRegistrationSuccess();
})
.catch(res => {
setError(res.error);
})
};
return(
<form className='RegistrationForm'
onSubmit={handleSubmit}
>
<div className='full_name'>
<label htmlFor='RegistrationForm__full_name'>
Full name
</label>
<Input
name='full_name'
type='text'
required
id='RegistrationForm__full_name'>
</Input>
</div>
<div className='user_name'>
<label htmlFor='RegistrationForm__user_name'>
User name
</label>
<Input
name='user_name'
type='text'
required
id='RegistrationForm__user_name'>
</Input>
</div>
<div className='password'>
<label htmlFor='RegistrationForm__password'>
Password
</label>
<Input
name='password'
type='password'
required
id='RegistrationForm__password'
>
</Input>
</div>
<div className='confirm-password'>
<label htmlFor="LoginForm__confirm-password">
Retype Password
</label>
<Input
name='confirm-password'
type="password"
required
id="LoginForm__confirm-password">
</Input>
</div>
{errorDiv}
<Button type='submit' variant='contained' color='default'>
Register
</Button>
</form>
)
}

Yes if you want exact error message from api response than you can get this by
.then(responseJson=> { console.log(responseJson.response.data.message) })

Have an API to check if the name is available or not, and hit the API when the user changes something in the input.
import React, { useState } from "react";
import ReactDOM from "react-dom";
let delayTimer;
function App() {
const [name, setName] = useState("");
const [nameAvailable, setNameAvailable] = useState(null);
async function checkNameAvailable() {
try {
const response = await APIUtility.isNameAvailable(name);
const { data = null } = response;
if (data) {
setNameAvailable(data); // data may be true or false
}
} catch (error) {
setNameAvailable(null);
}
}
function handleNameChange(e) {
setName(e.target.value);
if (name.length > 0) {
if (delayTimer) clearTimeout(delayTimer);
delayTimer = setTimeout(function() {
checkNameAvailable();
}, 1000); // Will do the ajax stuff after 1000 ms, or 1 s
}
}
return (
<form>
<label htmlFor="invite_code">Enter your name:</label>
<input
value={name}
onChange={handleNameChange}
type="text"
name="inviteCode"
id="invite_code"
autoComplete="off"
/>
{nameAvailable && <span>Name already taken</span>}
</form>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Related

Login Validation Wrong React Node js

i am creating a simple login form using frontend react backend node js.while attempt to login login failure. if we type wrong email and password alert msg displays login success. i don't know why.my backend i tested through postman it is work well.check through react had a problem.what i tried so far i attached below.
import axios from "axios";
import { useState } from "react";
import { useNavigate } from 'react-router-dom';
function Login() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const navigate = useNavigate();
async function login(event) {
event.preventDefault();
try {
await axios.post("http://localhost:9992/student/login", {
email: email,
password: password,
});
alert("Login Successfully");
// navigate('/home');
} catch (err) {
alert("ogin Failed");
}
}
return (
<div>
<div class="container">
<div class="row">
<h2>Login</h2>
<hr/>
</div>
<div class="row">
<div class="col-sm-6">
<form>
<div class="form-group">
<label>email</label>
<input type="email" class="form-control" id="email" placeholder="Enter Name"
value={email}
onChange={(event) => {
setEmail(event.target.value);
}}
/>
</div>
<div class="form-group">
<label>password</label>
<input type="password" class="form-control" id="password" placeholder="Enter Fee"
value={password}
onChange={(event) => {
setPassword(event.target.value);
}}
/>
</div>
<button type="submit" class="btn btn-primary" onClick={login} >Login</button>
</form>
</div>
</div>
</div>
</div>
);
I am using the data value based on your comment.
Modify your login function as following:
async function login(event) {
event.preventDefault();
try {
const res = await axios.post("http://localhost:9992/student/login", {
email: email,
password: password,
});
const data = res.data;
if (data.status === true) {
alert("Login Successfully");
} else {
alert("Login failed")
}
} catch (err) {
alert("Error, please try again");
}
}

How can I reset the form values in a React component with a button press?

I'm using the below Contact component to handle a simple form in react to send an email. I want the sendEmail function to also clear the form fields but I've tried referencing them through form.current and that doesnt seem to be working. Is there another way I need to reference them to set the values? I also tried e.target.reset() and it didn't seem to do anything.
import React, { useRef } from 'react';
import emailjs from 'emailjs-com';
const Contact = () => {
const form = useRef();
const sendEmail = (e) => {
e.preventDefault();
const serviceId='...';
const templateId='...';
const userId='...';
emailjs.sendForm(serviceId, templateId, form.current, userId)
.then((result) => {
console.log(result.text);
}, (error) => {
console.log(error.text);
});
};
return (
<form onSubmit={sendEmail} ref={form}>
<div className="field half first">
<label htmlFor="name">Name</label>
<input type="text" name="fromName" id="name"/>
</div>
<div className="field half">
<label htmlFor="email">Email</label>
<input type="text" name="fromEmail" id="email"/>
</div>
<div className="field">
<label htmlFor="message">Message</label>
<textarea name="message" id="message" rows="4"
placeholder = "..."></textarea>
</div>
<ul className="actions">
<li>
<input type="submit" value="Send Message" className="special"/>
</li>
</ul>
</form>
);
};
export default Contact
There are so many ways to doing this, basically on how the component has been structured to collect the data. However, following your pattern of arrangement, why don't you set a boolean variable or something coercible to a boolean value (value initially set to false) that is made aware (i.e value changes to true or 'sent') when the email has been successfully sent.
import {useState} from "react";
const [emailStatus, setEmailStatus] = useState("Not sent");
Then use the useEffect-hook to re-render the component, whenever the emailStatus variable changes to true or 'sent' and thereby clear-out the form values.
Hence, in your function:
emailjs.sendForm(serviceId, templateId, form.current, userId)
.then((result) => {
.... any other logic
console.log(result.text);
setEmailStatus('sent');
................
useEffect(() => {
//clear form fields here
}, [emailStatus]);
return(
.....
.....
);

Validation in Form with React js and Firebase

import React, { useState, useEffect } from "react";
import {db} from './firebase'
//I want to add some validation which perform task as follows
//1. Check user enter username less then 40 words
//2. Check user enter email (it need to check basic email information like # symbol)
//3. Check Message should not be exceed then 400 words ,
// All filed must be filled .
const Contact = () => {
const [senderName,setSenderName] = useState("");
const [senderEmail,setSenderEmail] = useState("");
const [senderMessage,setSenderMessage] = useState("");
const handleSubmitForm = (e) => {
e.preventDefault();
db.collection('Contact_Form').add({
User_name:senderName,
User_email:senderEmail,
User_message:senderMessage
})
.then(()=>{
alert("Message submitted")
})
.catch((error) => {
alert(error.message);
});
setSenderName("");
setSenderEmail("");
setSenderMessage("");
};
return(
<>
<div className="contact_us_body">
<div className="contact_us_container">
<div className="contact_us_content">
<div className="contact_us_right_side">
<div className="text_heading">Send us a message</div>
<form className="form" onSubmit={handleSubmitForm} >
<div className="contact_us_input_box">
<input type="text" placeholder="Enter your name" value={senderName}
onChange = {(e) => setSenderName(e.target.value)} />
</div>
<div className="contact_us_input_box">
<input type="text" placeholder="Enter your email"value={senderEmail}
onChange={(e) => setSenderEmail(e.target.value)} />
</div>
<div className="contact_us_input_box message-box">
<textarea name="messageText" id="" cols="30" rows="10"
placeholder="Type your Message"value={senderMessage}
onChange={(e) => setSenderMessage(e.target.value)} >
</textarea>
</div>
<div className="contact_us_button">
<input type="submit" value="Send Now" />
</div>
</form>
</div>
</div>
</div>
</div>
</>
)
}
export default Contact;
For Authenticating the Range of characters in username
function stringlength(inputtxt, maxlength)
{
var field = inputtxt.value;
var mxlen = maxlength;
if(field.length> mxlen)
{
alert("Please input the userid between " +mnlen+ " and " +mxlen+ " characters");
return false;
}
}
If you are using Firebase than you can use firebase Authentication for the login and it will take care of the email formatting-
first of all, define 2 additional useState to show the errors,
const [emailError, setEmailError] = useState('');
const handleLogin = () => {
db
.auth()
.signInWithEmail(email)
.catch((err) =>{
switch (err.code){
case "auth/invalid-email":
// console.log(err)
setEmailError(err.message);
break;
}
})
}
For Limiting the Characters in the tag, use the following attribute
<textarea maxlength="400">

How to write validations for email and password using react hooks

I am working on React in that project I am trying to write validations for Email and password by
using react hooks But I don't know how to start it write it so please help to achieve this.
What I want exactly is I hard coded Email and Password in my code. Now Just I want to write validations for Email and Password. What I want exactly is If I enter Incorrect Email and Correct password then in Validations it have to show only please enter valid email address.
If I enter correct Email then it has to show please enter correct password. If both are wrong means then it has to show validations please enter correct Email and Password.
This is my code
import React, { useState } from 'react';
import './Login.css';
const Login = () => {
const [loginData, setLoginData] = useState(null)
const loginCredentials = () => {
if (loginData.email === 'john#gmail.com' && loginData.password === 'christina') {
} else {
}
}
const handleChange = ({ target }) => {
const { name, value } = target
const newData = Object.assign({}, loginData, { [name]: value })
setLoginData(newData)
}
const handleSubmit = (e) => {
e.preventDefault()
loginCredentials()
}
return (
<div className='container'>
<div className='row justify-content-center'>
<div className='col-4'>
<div className='mainform mt-3'>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="email">Email</label>
<input type="email" name='email' className="form-control" id="email" onChange={handleChange}></input>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input type="password" name='password' className="form-control" id="password" onChange={handleChange}></input>
</div>
<button type="submit" className="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
</div>
)
}
export default Login
Try saving the errors in an array and check the length of array at the end.
const [errors,setErrors]=useState([]);
.
.
.
if(username !='john#gmail.com')
{
setErrors([...errors,{error:'Invalid username'}])
}
if(password!='something')
{
setErrors([...errors,{error:'Invalid password'}])
}
Now inside of the component
{errors?errors.map(elem=>elem.error):null}
You can create a state for the error message and change its value based on what combination of email and password is incorrect. If
const [errorMessage, setErrorMessage] = useState('')
const loginCredentials = () => {
if (loginData.email !== 'john#gmail.com' && loginData.password !== 'christina') {
setErrorMessage('email and pw are both incorrect')
} else if (loginData.email !== 'john#gmail.com' {
setErrorMessage('email is incorrect')
} else if {.....etc
}
then put {errorMessage} in your jsx where you want it to show up
You can use nested if else
const [error, setError] = useState("");
const loginCredentials = () => {
if (loginData.email === "john#gmail.com") {
if (loginData.password === "christina") {
setError("");
return true;
}
else
{
setError("Incorrect Password");
return false;
}
} else {
setError("Incorrect Email and password");
return false;
}
};
To show the error you can put a div somewhere in the form which will only show when there is error.
{error && <div>{error}</div>}
First of all, your input values are not controlled elements. learn about 'controlled component'.
There are lots of ways you can achieve this.
I think you can add a custom hook to handle onChange and reset handler.
custom hook:
import { useState } from 'react';
const useInputState = (initialValues) => {
const [state, setstate] = useState(initialValues);
const onChangeHandler = (e) => setstate({
...state,
[e.target.name]: e.target.value,
});
const reset = (field) => {
if (field) {
setstate({
...state,
[field]: initialValues[field],
});
} else {
setstate({
...initialValues,
});
}
};
return [state, onChangeHandler, reset];
};
export default useInputState;
Then consume that hook in your component.
import React, { useState } from 'react';
import UseInputState from '../hooks/useInputState';
const App = () => {
const [value, onChangeHandler, reset] = UseInputState('');
console.log({ value });
const [emailAlert, setEmailAlert] = useState(null);
const [passwordAlert, setPasswordAlert] = useState(null);
const loginCredentials = () => {
setEmailAlert(null);
setPasswordAlert(null);
const { email, password } = value;
if (email !== 'john#gmail.com') {
setEmailAlert('Please Enter valid Email Address');
}
if (password !== 'christina') {
setPasswordAlert(' please enter correct password');
}
reset('');
if (password === 'christina' && email === 'john#gmail.com') {
setEmailAlert(null);
setPasswordAlert(null);
}
};
const handleSubmit = (e) => {
e.preventDefault();
loginCredentials();
};
return (
<div className='container'>
<div className='row justify-content-center'>
<div className='col-4'>
<div className='mainform mt-3'>
<form onSubmit={handleSubmit}>
<div className='form-group'>
<label htmlFor='email'>Email</label>
<input
type='email'
name='email'
className='form-control'
id='email'
value={value.email || ''}
onChange={onChangeHandler}
></input>
</div>
<div className='form-group'>
<label htmlFor='password'>Password</label>
<input
type='password'
name='password'
className='form-control'
id='password'
value={value.password || ''}
onChange={onChangeHandler}
></input>
</div>
<button type='submit' className='btn btn-primary'>
Submit
</button>
</form>
{emailAlert && <div>{emailAlert}</div>}
{passwordAlert && <div>{passwordAlert}</div>}
</div>
</div>
</div>
</div>
);
};
export default App;

values on handleSubmit() shows undefined in console log

The same code worked well in the Previous machine.
Now for some reason, the values in console (in handleSubmit()) shows undefined for email, fullName, and password and then it reaches catch block saying something went wrong! Help.
I have a Signup form:
export default function MerchantCreateAccountForm() {
Constants such as email, password and name are defined in it:
// set error messages to display to the user
const [nameError, setNameError] = useState(null);
const [emailError, setEmailError] = useState(null);
const [passwordError, setPasswordError] = useState(null);
// set initial state value(s)
const [fullName, setFullName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [errors, setErrors] = useState({});
const authContext = useContext(AuthContext);
Mainly, NEED HELP HERE FOR undefined VALUES FOR email, fullName AND password in handleSubmit()
Later it reaches to catch block(something went wrong) but that can be another issue.
Here's the function:
const handleSubmit = (e) => {
try {
e.preventDefault();
console.log("email is: " +email); //showing undefined in console. HELP
console.log("name is: "+fullName); //showing undefined in console. HELP
console.log("password is: "+password); //showing undefined in console. HELP
const merchantSignupData =
{
data:
{
name: fullName,
email: email,
password: password,
client_id: 'testclient',
client_secret: 'testpass'
},
type: 'POST',
url: 'merchant-signup',
success: authContext.merchantSignupSuccess,
error: authContext.networkError
};
merchantSignupObject.fullName, merchantSignupObject.password);
authContext.merchantSignup(merchantSignupData);
}
catch{
console.log("something went wrong!");
//need to add error handling here
}
}
I have used validations here although, that works fine, just in case if this might be hampering of setting up the data:
// for every change in our state this will be fired
// we add validation here and disable the save button if required
useEffect(() => {
// we want to skip validation on first render
if (firstRender.current) {
firstRender.current = false
return
}
// here we can disable/enable the save button by wrapping the setState function
// in a call to the validation function which returns true/false
//setDisabled(formValidation())
formValidation();
}, [fullName, password]) // any state variable(s) included in here will trigger the effect to run
// here we run any validation, returning true/false
const formValidation = () => {
let newErrors = {}
var error = false;
if (fullName === "") {
newErrors.fullName = 'Name cant be blank!'
}
if (email === "") {
newErrors.email = 'Email cant be blank!'
}
if (!(/.+#.+\.[A-Za-z]+$/.test(email))) {
newErrors.email = 'Enter a valid email id';
}
if (!(/(?=.{7,255}$)(?=.*[A-Z])(?=.*[a-z])(?=.*\d)/.test(password))) {
newErrors.password = 'Invalid Password Format';
}
setNameError(errors.name)
setEmailError(errors.email)
setPasswordError(errors.password)
if (errors != null) {
//alert("reached")
setErrors(newErrors);
// $("#signup-submit").addremoveAttr("disabled")
}
else {
alert("reached here")
setNameError(errors.fullName)
setEmailError(errors.email)
setPasswordError(errors.password)
// $("#signup-submit").removeAttr("disabled")
}
}
const showError = () => {
alert('error!');
}
And here's my main form:
return (
<form onSubmit={handleSubmit()}>
<div className="row">
<div className="col-md-4 col-sm-6 col-xs-12">
<div className="signup">
<h3>{lang.merchant_signup_create_account}</h3>
<p>{lang.merchant_signup_account_already}{lang.merchant_signup_sign_in}</p>
<div className="form-group has-error">
<input type="text" required="required" name="fullName"
value={fullName}
placeholder={lang.merchant_signup_name_placeholder}
onChange={e => setFullName(e.target.value)} />
<label htmlFor="input" className="control-label">{lang.merchant_signup_name}</label>
<i className="bar"></i>
<div className="error">
<div className="error-msg" role="alert">
{errors.fullName && <p>{errors.fullName}</p>}
</div>
</div>
</div>
<div className="form-group">
<input type="text" required="required"
placeholder={lang.merchant_signup_email_placeholder} onChange={e => setEmail(e.target.value)} />
<label htmlFor="E-mail" className="control-label">{lang.merchant_signup_email}</label><i className="bar"></i>
<div className="error">
<div className="error-msg" role="alert">
{errors.email && <p>{errors.email}</p>}
</div>
</div>
</div>
<div className="form-group">
<input type="password" required="required" placeholder={lang.merchant_signup_password_placeholder} onChange={e => setPassword(e.target.value)} />
<label htmlFor="Password" className="control-label">{lang.merchant_signup_password}</label><i className="bar"></i>
<div className="error">
<div className="error-msg" role="alert">
{errors.password && <p>{errors.password}</p>}
</div>
</div>
<ul className="p-suggest">
<li> {lang.merchant_signup_password_validation1}</li>
<li>{lang.merchant_signup_password_validation2}</li>
</ul>
<ul className="p-suggest">
<li>{lang.merchant_signup_password_validation3}</li>
<li>{lang.merchant_signup_password_validation4}</li>
</ul>
</div>
<p>{lang.merchant_signup_create_terms_warning}<a target="_blank" href="#">{lang.merchant_terms_condition}</a>.</p>
</div>
<ul className="list-inline">
{/* onClick={() => handleSubmit()} */},
<li><button type="submit" id="signup-submit" className="btn btn-danger create-account next-step">{lang.merchant_signup_create_account_btn}</button></li>
</ul>
</div>
<div className="col-md-8 col-sm-6 col-xs-12">
<img className="img-responsive" src={storeImg} />
</div>
</div>
</form>
)
}
As you can read see here,
Make sure you aren’t calling the function when you pass it to the component:
So, change your form onSubmit method invocation to
<form onSubmit={handleSubmit}>
or
<form onSubmit={() => handleSubmit()}>
Back to basics, Silly solution:
The attribute value is missing in each input and it was henceforth taking value to be undefined like following:
<input value={password} type="password" required="required" placeholder={lang.merchant_signup_password_placeholder} onChange={e => setPassword(e.target.value)} />

Resources