Reputation: 525
I am building a react login page that uses Django Rest Token authentication. I am at the process of creating error messages in the login page. But one of the errors I created is not displaying correctly. The error message is supposed to display after a user has clicked the login button (handleSubmit
). But the error displays after the user additionally inputs a change (handleChange )
in the input. I can't seem to trace where I did an error in my code. Some help would be appreciated. Thanks.
The error that does not display correctly is, it is in my code below, I enclosed it in **
so you could easily identify it. :-
{wrongcredentials ? <div className="errorMessage">Wrong username or password</div> : null}
Below is the core section of my code :
const formValid = ({formErrors, ...rest})=> {
let valid = true;
Object.values(formErrors).forEach(val =>{
val.length > 0 && (valid = false)
});
Object.values(rest).forEach(val =>{
!(val) && (valid = false)
});
return valid;
}
let isloading = false;
let wrongcredentials = false;
class Login extends Component{
constructor(props){
super(props)
this.state = {
credentials : {username :null, password :null},
formErrors :{
username :'',
password :'',
}
};
}
handleSubmit = e => {
e.preventDefault()
if(formValid(this.state)){
fetch('http://195.154.26.202:8000/auth/', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(this.state.credentials)
}).then( data => data.json())
.then(
data => {
console.log('token', data.token)
if(data.token="undefined"){
console.error('wrong username or password')
wrongcredentials = true
}else{
window.location.href = '/';
isloading = true;
}
this.props.userLogin(data.token);
}
)
console.log(`
--SUBMITTING--
username: ${this.state.credentials}
password : ${this.state.credentials}
`)
}else{
console.error('FORM INVALID')
}
}
handleChange = e => {
e.preventDefault()
const cred = this.state.credentials;
cred[e.target.name] = e.target.value;
let formErrors = this.state.formErrors;
switch(e.target.name){
case 'username' :
formErrors.username = e.target.value.length>0 && e.target.value.length<3 ? 'minumum 3 characters required':
e.target.value.length==0? 'username is required': '';
break;
case 'password' :
formErrors.password = e.target.value.length>0 && e.target.value.length<6 ? 'minumum 6 characters required':
e.target.value.length==0? 'password is required': '';
break;
default:
break;
}
this.setState({credentials: cred}, ()=> console.log(this.state))
}
render() {
const {formErrors} = this.state
console.log('wrong', wrongcredentials)
return(
<div className="Login">
<div className="nav-bar">
<div className="title-section">
<h6>lobstr.io</h6>
</div>
</div>
<div className="wrapper">
<form>
<Heading>Sign In</Heading>
<Input
autoFocus
type="text"
className={formErrors.username.length>0? 'error': null}
name="username"
noValidate
placeholder="username"
onChange={this.handleChange}/>
{formErrors.username.length>0 && (
<span className="errorMessage">{formErrors.username}</span>
)}
<Input
name="password"
placeholder="Password"
onChange={this.handleChange}
type="password"
className={formErrors.password .length>0 ? 'error': null}/>
{formErrors.password .length>0 && (
<span className="errorMessage">{formErrors.password}</span>
)}
<div className="additional">
<FormGroup>
<FormCheck type="checkbox" value="remember" label="Remember me" />
</FormGroup>
<Link to ='/forgot-credentials'>Forgot credentials</Link>
</div>
<Button className="loginbtn" block bsSize="large" onClick={!isloading ? this.handleSubmit : null}>
{isloading ? 'Loading…' : 'Sign in'}
</Button>
**{wrongcredentials ? <div className="errorMessage">Wrong username or password</div> : null}**
</form>
<Footer>
<div className="company-login">
<p className="title-login">Pharmacy</p>
<h6 className="subtitle-login">Database Visualization</h6>
</div>
</Footer>
</div>
</div>
)
}
}
Upvotes: 0
Views: 128
Reputation: 1
You specify wrongcredentials as global variable not state variable. The scenario happen is:
first time wrongcredentials= false
issue will not occur if user add data in input field for first time, error message is showing when user click on submit button once and after that change input field, right?
because you set wrongcredentials= true if user click on submit button and token is undefined, but the error will not be shown on screen as re render is not happening. -and after that if user change value now the wrongcredentials value is true and re-render occurs so issue displayed on screen
for complete functioning please set wrongcredentials as state variable
Upvotes: 0
Reputation: 92
Initialize wrongcredentials varaible into your components state and set it to true on error it will only rerender then ...
constructor(props){
super(props)
this.state = {
credentials : {username :null, password :null},
formErrors :{
username :'',
password :'',
},
wrongcredentials: false
};
}
...
...
.then(
data => {
console.log('token', data.token)
if(data.token="undefined"){
console.error('wrong username or password')
this.setState({...this.state, wrongcredentials: true})
}else{
window.location.href = '/';
isloading = true;
}
this.props.userLogin(data.token);
}
)
...
Upvotes: 2