简体   繁体   English

保存用户前如何检查电子邮件是否存在

[英]How to check if email exist before save the user

I'm starting nodeJS / MongoDB and I'm trying to create a simple auth API. 我正在启动nodeJS / MongoDB,并且试图创建一个简单的auth API。 I began by the SignIn function, but I have some difficulties with async functions when I check my form values. 我从SignIn函数开始,但是在检查表单值时,我在使用异步函数时遇到了一些困难。 I try to check every values before save a row in database. 在数据库中保存一行之前,我尝试检查每个值。 So I check password and email format, and my difficulties begin when I want to check if the email already exist. 因此,我检查密码和电子邮件格式,当我想检查电子邮件是否已经存在时,我的麻烦就开始了。

Here you can see my function called when I submit my form : 在这里,您可以看到我提交表单时调用的函数:

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
    }
}

And here my function checkEmailExist who check in db 这是我的功能checkEmailExist谁签入数据库

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 };
}

My goal is to get the error returned from the checkEmailExist function, and send this errors to the FRONT with the others errors. 我的目标是获取来自checkEmailExist函数返回的错误,并将此错误与其他错误一起发送至FRONT。 But findOne is an async function and the query is always pending when I check my array of errors if (Object.keys(errors).length > 0) { . 但是findOne是一个异步函数, if (Object.keys(errors).length > 0) {当我检查错误数组时,查询始终处于待处理状态。 So the user can be saved with and existing email. 因此,用户可以与现有电子邮件一起保存。

How can I properly check if email exist before saving the user ? 保存用户之前,如何正确检查电子邮件是否存在?

Thanks 谢谢

Solution one : use checkEmailExist when user type the email in textfield using onchange or leaving the email field. 解决方案一:当用户使用onchange在文本字段中键入电子邮件或离开电子邮件字段时,请使用checkEmailExist。

Solution two : Use ES6 ASYNC/AWAIT to hold the flow until return true or false from checkEmailExist method. 解决方案二:使用ES6 ASYNC / AWAIT保持流,直到从checkEmailExist方法返回true或false。

REMOVE .then query... why do you need then if your are using await... 删除。然后查询...如果您正在使用等待,那么为什么需要...

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


looks like you're mixing a .then with an await. 看起来您正在将.then与等待混合。 i confess to not being an expert on async/await here, especially when mixed with promises, but could your checkEmailExist function look like: 我承认这里不是异步/等待方面的专家,尤其是当与promises混合使用时,但您的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;
}

?

not sure if it makes a difference, but mixing the await and the then seems like it might give you unexpected results 不确定是否会有所不同,但将await和then混合使用可能会给您带来意想不到的结果

The problem at Object.keys(allFields).forEach(async field . The code inside foreach is async function, so it intermediately execute and the next line of code not waiting for it to end. You should make signUp async : export async function signUp and replace forEach with a regular loop: 问题在Object.keys(allFields).forEach(async field内部的代码是async函数,因此它处于中间执行状态,下一行代码不等待其结束,您应该使signUp asyncexport async function signUp并用常规循环替换forEach

for (const field in allFields) {
   ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM