Fix async validation in signup form (fixes #742) (#746)

This commit is contained in:
anaplian 2018-10-29 23:33:37 +00:00 committed by Cassie Tarakajian
parent de74c0cac8
commit 319e68ddb6
3 changed files with 52 additions and 18 deletions

View file

@ -59,10 +59,26 @@ class SignupView extends React.Component {
} }
} }
function asyncErrorsSelector(formName, state) {
const form = state.form[formName];
if (!form) {
return {};
}
const fieldNames = Object.keys(form).filter(key => !key.startsWith('_'));
return fieldNames.reduce((asyncErrors, fieldName) => {
if (form[fieldName].asyncError) {
return { ...asyncErrors, [fieldName]: form[fieldName].asyncError };
}
return asyncErrors;
}, {});
}
function mapStateToProps(state) { function mapStateToProps(state) {
return { return {
user: state.user, user: state.user,
previousPath: state.ide.previousPath previousPath: state.ide.previousPath,
asyncErrors: asyncErrorsSelector('signup', state)
}; };
} }
@ -71,21 +87,29 @@ function mapDispatchToProps(dispatch) {
} }
function asyncValidate(formProps, dispatch, props) { function asyncValidate(formProps, dispatch, props) {
const fieldToValidate = props.form._active; const errors = {};
if (fieldToValidate) { return Promise.resolve(true)
const queryParams = {}; .then(() => {
queryParams[fieldToValidate] = formProps[fieldToValidate]; const fieldToValidate = props.form._active;
queryParams.check_type = fieldToValidate; if (fieldToValidate) {
return axios.get('/api/signup/duplicate_check', { params: queryParams }) const queryParams = {};
.then((response) => { queryParams[fieldToValidate] = formProps[fieldToValidate];
if (response.data.exists) { queryParams.check_type = fieldToValidate;
const error = {}; return axios.get('/api/signup/duplicate_check', { params: queryParams })
error[fieldToValidate] = response.data.message; .then((response) => {
throw error; if (response.data.exists) {
} errors[fieldToValidate] = response.data.message;
}); }
} });
return Promise.resolve(true).then(() => {}); }
return null;
})
.then(() => {
const err = { ...errors, ...props.asyncErrors };
if (Object.keys(err).length > 0) {
throw err;
}
});
} }
function onSubmitFail(errors) { function onSubmitFail(errors) {

View file

@ -45,3 +45,7 @@
.form input[type="submit"] { .form input[type="submit"] {
@extend %forms-button; @extend %forms-button;
} }
.form input[type="submit"]:disabled {
cursor: not-allowed;
}

View file

@ -38,7 +38,12 @@ export function createUser(req, res, next) {
}); });
User.findOne( User.findOne(
{ email: req.body.email }, {
$or: [
{ email: req.body.email },
{ username: req.body.username }
]
},
(err, existingUser) => { (err, existingUser) => {
if (err) { if (err) {
res.status(404).send({ error: err }); res.status(404).send({ error: err });
@ -46,7 +51,8 @@ export function createUser(req, res, next) {
} }
if (existingUser) { if (existingUser) {
res.status(422).send({ error: 'Email is in use' }); const fieldInUse = existingUser.email === req.body.email ? 'Email' : 'Username';
res.status(422).send({ error: `${fieldInUse} is in use` });
return; return;
} }
user.save((saveErr) => { user.save((saveErr) => {