Skip to content

Commit 319e68d

Browse files
anapliancatarak
authored andcommitted
Fix async validation in signup form (fixes #742) (#746)
1 parent de74c0c commit 319e68d

File tree

3 files changed

+52
-18
lines changed

3 files changed

+52
-18
lines changed

client/modules/User/pages/SignupView.jsx

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,26 @@ class SignupView extends React.Component {
5959
}
6060
}
6161

62+
function asyncErrorsSelector(formName, state) {
63+
const form = state.form[formName];
64+
if (!form) {
65+
return {};
66+
}
67+
68+
const fieldNames = Object.keys(form).filter(key => !key.startsWith('_'));
69+
return fieldNames.reduce((asyncErrors, fieldName) => {
70+
if (form[fieldName].asyncError) {
71+
return { ...asyncErrors, [fieldName]: form[fieldName].asyncError };
72+
}
73+
return asyncErrors;
74+
}, {});
75+
}
76+
6277
function mapStateToProps(state) {
6378
return {
6479
user: state.user,
65-
previousPath: state.ide.previousPath
80+
previousPath: state.ide.previousPath,
81+
asyncErrors: asyncErrorsSelector('signup', state)
6682
};
6783
}
6884

@@ -71,21 +87,29 @@ function mapDispatchToProps(dispatch) {
7187
}
7288

7389
function asyncValidate(formProps, dispatch, props) {
74-
const fieldToValidate = props.form._active;
75-
if (fieldToValidate) {
76-
const queryParams = {};
77-
queryParams[fieldToValidate] = formProps[fieldToValidate];
78-
queryParams.check_type = fieldToValidate;
79-
return axios.get('/api/signup/duplicate_check', { params: queryParams })
80-
.then((response) => {
81-
if (response.data.exists) {
82-
const error = {};
83-
error[fieldToValidate] = response.data.message;
84-
throw error;
85-
}
86-
});
87-
}
88-
return Promise.resolve(true).then(() => {});
90+
const errors = {};
91+
return Promise.resolve(true)
92+
.then(() => {
93+
const fieldToValidate = props.form._active;
94+
if (fieldToValidate) {
95+
const queryParams = {};
96+
queryParams[fieldToValidate] = formProps[fieldToValidate];
97+
queryParams.check_type = fieldToValidate;
98+
return axios.get('/api/signup/duplicate_check', { params: queryParams })
99+
.then((response) => {
100+
if (response.data.exists) {
101+
errors[fieldToValidate] = response.data.message;
102+
}
103+
});
104+
}
105+
return null;
106+
})
107+
.then(() => {
108+
const err = { ...errors, ...props.asyncErrors };
109+
if (Object.keys(err).length > 0) {
110+
throw err;
111+
}
112+
});
89113
}
90114

91115
function onSubmitFail(errors) {

client/styles/components/_forms.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,7 @@
4545
.form input[type="submit"] {
4646
@extend %forms-button;
4747
}
48+
49+
.form input[type="submit"]:disabled {
50+
cursor: not-allowed;
51+
}

server/controllers/user.controller.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,21 @@ export function createUser(req, res, next) {
3838
});
3939

4040
User.findOne(
41-
{ email: req.body.email },
41+
{
42+
$or: [
43+
{ email: req.body.email },
44+
{ username: req.body.username }
45+
]
46+
},
4247
(err, existingUser) => {
4348
if (err) {
4449
res.status(404).send({ error: err });
4550
return;
4651
}
4752

4853
if (existingUser) {
49-
res.status(422).send({ error: 'Email is in use' });
54+
const fieldInUse = existingUser.email === req.body.email ? 'Email' : 'Username';
55+
res.status(422).send({ error: `${fieldInUse} is in use` });
5056
return;
5157
}
5258
user.save((saveErr) => {

0 commit comments

Comments
 (0)