Success Message Continues Fire Despite Error State In Semantic-React-UI Form
I am trying to get the appropriate messages to fire depending on the state of my form component for front end validation on form submit.
One of the main validations I'm working on is checking if a email exists and if so one should continue to see the error message fire. If it doesn't exist in the database a success message should fire; And of course if the other validations pass!.
I am using Semantic-UI React Forms to help with validation.
These are the key and values which I have set on the state object in my form component:
this.state = {
fadeUp: 'fade up',
duration: 500,
username: '',
password: '',
usernameError: false,
passwordError: false,
formSuccess: false,
formError: false,
userNameDup: false,
}
This is my submit handler which fires upon submit:
handleSubmit(event) {
event.preventDefault();
var error = false
var { username, password, userNameDup } = this.state
var mailFormat = /^(([^<>()\[\]\\.,;:\[email protected]"]+(\.[^<>()\[\]\\.,;:\[email protected]"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
if (!username.match(mailFormat)) {
this.setState({ usernameError: true });
error = true;
} else {
this.setState({ usernameError: false });
}
if (password.length < 8) {
this.setState({ passwordError: true });
error = true;
} else {
this.setState({ passwordError: false })
}
if (error) {
this.setState({ formSuccess: false });
return;
} else {
this.setState({ formSuccess: true });
}
window.fetch('http://localhost:8016/users/registration', {
method: 'POST',
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
body: JSON.stringify({ username_email: username, password: password })
})
.then(this.handleErrors)
.then(function (response) {
console.log(`response ${response}`)
return response.json()
}).then(function (data) {
console.log('User created:', data)
}).catch(function (error) {
console.log(error);
});
setTimeout(() => { this.setState({ username: '', password: '' }) })
}
handleErrors(response) {
if (!response.ok) {
if (response.status === 409) {
console.log("response.status ", response.status);
this.setState({
userNameDup: true, formError: true, formSuccess:false
});
return;
}
} else {
this.setState({
userNameDup: false, formError:false
})
}
return response;
}
This is a portion of the form view/markup:
{console.log("formSuccess 1", formSuccess)}
<Form size='large'
onSubmit={this.handleSubmit}
error={userNameDup || formError}>
{console.log("formSuccess 2", formSuccess)}
<Segment stacked>
<Form.Input fluid icon='user'
iconPosition='left'
placeholder='E-mail address, e.g. [email protected]'
name='username'
value={username}
onBlur={this.handleBlur}
onChange={this.handleChange}
error={usernameError}
/>
<Transition visible={usernameError}
animation='scale'
duration={duration}>
<Message error content='username_Email is in incorrect format e.g. [email protected]' />
</Transition>
<Form.Input fluid icon='lock'
iconPosition='left'
placeholder='Password'
name='password'
value={password}
onBlur={this.handleBlur}
onChange={this.handleChange}
error={passwordError}
/>
<Transition visible={passwordError}
animation='scale'
duration={duration}>
<Message error content='Password needs to be greater than eight characters.' />
</Transition>
<Button color='teal'
fluid size='large'
disabled={!username || !password}>
Register
{/* {isLoggedIn ? `Register` : `Log-in`} */}
</Button>
<Transition visible={userNameDup || formError}
unmountOnHide={true}
animation='scale'
duration={duration}>
<Message
error
centered="true" header='This email exists.'
content='Please re-enter another email address.' />
</Transition>
<Transition visible={formSuccess}
unmountOnHide={true}
animation='scale'
duration={duration}>
<Message
success
header='Your user registration was successful.'
content='You may now log-in with the username you have chosen.' />
</Transition>
</Segment>
</Form>
I supplied a and you can see the
formSuccess
key jumps to true
for a second which causes the problem. But I thought my handleError
is taking care of that on submit?
handleError again:
handleErrors(response) {
if (!response.ok) {
if (response.status === 409) {
console.log("response.status ", response.status);
this.setState({
userNameDup: true, formError: true, formSuccess:false /* why doesn't it stay falsey? */
});
return;
}
} else {
this.setState({
userNameDup: false, formError:false
})
}
return response;
}
Excerpt from handle submit:
window.fetch('http://localhost:8016/users/registration', {
method: 'POST',
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
body: JSON.stringify({ username_email: username, password: password })
})
.then(this.handleErrors) /* Shouldn't this be where it changes to false? */
.then(function (response) {
console.log(`response ${response}`)
return response.json()
}).then(function (data) {
console.log('User created:', data)
}).catch(function (error) {
console.log(error);
});
Also shouldn't the message animate every time one would hit register?
Please help!!! And thank you!
Answer
if (error) {
this.setState({ formSuccess: false });
return;
} else {
this.setState({ formSuccess: true });
}
When you hit submit, the initial value for the error
variable is false, so it changes the formSuccess
state to true until the promise is resolved - when handleErrors
is called and changes it back to false. You should only set formSuccess
to true after you fetch the data from db, that is, inside .then()
block to avoid async issues.
One approach to solving it is to display the success message after you fetched the data and validated the user is new like so:
handleErrors(response) {
if (!response.ok) {
if (response.status === 409) {
console.log("response.status ", response.status);
this.setState({
userNameDup: true, formError: true, formSuccess:false
});
return;
}
} else {
this.setState({
userNameDup: false, formError:false, formSuccess: true
})
}
return response;
}
And then your frontend validation is restricted to only showing the error message.
if (!username.match(mailFormat)) {
this.setState({ usernameError: true, formSuccess: false } });
} else {
this.setState({ usernameError: false });
}
if (password.length < 8) {
this.setState({ passwordError: true, formSuccess: false } });
} else {
this.setState({ passwordError: false })
}
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM