Как проверить, существует ли электронная почта перед сохранением пользователя - PullRequest
0 голосов
/ 21 февраля 2019

Я запускаю nodeJS / MongoDB и пытаюсь создать простой API аутентификации.Я начал с функции SignIn, но у меня возникли некоторые трудности с асинхронными функциями при проверке значений формы.Я пытаюсь проверить все значения, прежде чем сохранить строку в базе данных.Поэтому я проверяю пароль и формат электронной почты, и мои трудности начинаются, когда я хочу проверить, существует ли уже электронная почта.

Здесь вы можете увидеть, как моя функция вызывается при отправке формы:

export function signUp(req, res) {
    const { email, password, confirmPassword } = req.body || '';
    const allFields = { email, password, confirmPassword };

    let errors = {};
    Object.keys(allFields).forEach(async field => {
        const value = allFields[field];

        if (value === '') {
            errors = {...errors, [field]: 'Ce champ est requis'}
        } else {
            if (field === 'email') {
                if (!checkEmailFormat(value)) {
                    errors = {...errors, [field]: 'Le format de mail n\'est pas valide'}
                } else {
                    const { error, exist } = await checkEmailExist(value);
                    if (exist) {
                        console.log(exist);
                        console.log(error);
                        errors = {...errors, ...error};
                    }
                }
            }
            if (field === 'password' && password !== '' && password < 6) {
                errors = {...errors, [field]: 'Le mot de passe doit contenir plus de 6 caractères'}
            }
        }
    });

    console.log(errors);
    console.log(Object.keys(errors).length);
    console.log('--------------------');

    // Retour des erreurs vers le FRONT ou Save de l'user
    if (Object.keys(errors).length > 0) {
        console.log(errors);
        res.json({ errors });
    } else {
        ...Save my row in db
    }
}

И здесь моя функция checkEmailExist, которая регистрирует в db

const checkEmailExist = async (value) => {
    const { error, exist } = await User.findOne({'email': value}).exec()
        .then(user => {
            let res = {};
            if (user) {
                res = { error: { 'email': "Cet adresse email n'est pas disponible" }, exist: true };
            } else {
                res = { error: { 'email': "" }, exist: false };
            }
            return res;
        })
        .catch(err => console.log(err))

    return { error, exist };
}

Моя цель - получить ошибку, возвращаемую функцией checkEmailExist, и отправить эти ошибки в FRONT с другими ошибками.Но findOne - это асинхронная функция, и запрос всегда выполняется, когда я проверяю свой массив ошибок if (Object.keys(errors).length > 0) {.Таким образом, пользователь может быть сохранен с существующей электронной почтой.

Как правильно проверить, существует ли электронная почта перед сохранением пользователя?

Спасибо

Ответы [ 3 ]

0 голосов
/ 21 февраля 2019

похоже, что вы смешиваете. То с ожиданием.я признаюсь, что не являюсь экспертом по асинхронности / ожиданию здесь, особенно в сочетании с обещаниями, но может ли ваша функция checkEmailExist выглядеть следующим образом:

const checkEmailExist = async (value) => {
    const user = await User.findOne({'email': value}).exec()
        .catch(err => console.log(err))

    let res = {};
    if (user) {
        res = { error: { 'email': "Cet adresse email n'est pas disponible" }, exist: true };
    } else {
        res = { error: { 'email': "" }, exist: false };
    }
    return res;
}

?

не уверен, что это имеет значение, но смешивание await и then может привести к неожиданным результатам

0 голосов
/ 21 февраля 2019

Проблема на Object.keys(allFields).forEach(async field.Код внутри foreach является функцией async, поэтому он выполняется промежуточно, и следующая строка кода не ожидает его завершения.Вы должны сделать signUp async: export async function signUp и заменить forEach обычным циклом:

for (const field in allFields) {
   ...
}
0 голосов
/ 21 февраля 2019

Решение первое: используйте checkEmailExist, когда пользователь вводит электронную почту в текстовое поле, используя onchange или оставляя поле электронной почты.

Решение второе: используйте ES6 ASYNC / AWAIT, чтобы удерживать поток до тех пор, пока не вернет true или false из метода checkEmailExist.

УДАЛИТЬ. Тогда запрос ... зачем вам тогда, если вы используете await ...

const checkEmailExist = async (value) => {
    const { error, exist } = await User.findOne({'email': value}).exec()
    return { error, exist };
}


...