简体   繁体   English

如何使用 Formik 和 Yup 进行服务器端验证?

[英]How to do I do server side validation using Formik and Yup?

I'm trying to validate a email field on a sign up form to check if it already exist.我正在尝试验证注册表单上的电子邮件字段以检查它是否已经存在。 To do this I'm checking the running a GET request on the server that returns true and false.为此,我正在检查在服务器上运行一个返回 true 和 false 的 GET 请求。

This is my validation Schema for the field:这是我对该字段的验证架构:

validationSchema={
    yup.object().shape({
        registrationEmail: yup.string().email('Invalid email').test('Unique Email','Email already in use', async (value) => {axios.get('http://localhost:5000/users/register', value).catch(err => console.log(err)) })
    })
}

The problem seems to be that the values field is blank.问题似乎是值字段为空。 How do I past the value from the Formik Field to my function?如何将 Formik 字段中的值传递给我的函数?

EDIT: Managed to send value using the following编辑:管理使用以下发送值

registrationEmail: yup.string().email('Invalid email').test('Unique Email','Email already in use', function(value){return new Promise((resolve, reject) => {axios.get('http://localhost:5000/users/register', value)})})

I'm still having troubles returning a response this is what the route looks like我仍然无法返回响应,这就是路由的样子

router.get('/register', (req, res) => {
    User.findOne({email: req.body.email}).then(user => {
        if(user){
            return true
        }else{
            return false
        }
    })
})

I solved my problem for the validation I did the following:我解决了验证问题,我执行了以下操作:

 registrationEmail: yup.string().email('Invalid email')
                        .test('Unique Email','Email already in use', 
                            function(value){return new Promise((resolve, reject) => {
                                axios.post('http://localhost:5000/users/register/validEmail', {'email': value})
                                .then(res => {if(res.data.msg === 'Username already been taken'){resolve(false)} resolve(true)})
                            })}
                        )

For the route:对于路线:

router.post('/register/validEmail', (req, res) => {
    console.log('Request: ', req.body)
    User.findOne({email: req.body.email}).then(user => {
        if(user){
            console.log({ msg:"Username already been taken" })
            return res.json({ msg:"Username already been taken" })
        }

        console.log({ msg: "Username available." })
        return res.json({ msg: "Username available." })

    }).catch((err)=>{
        console.error(err);
        res.status(400).json('Error: ' + err)
    })
})

Turns out I had to use a POST request or the body of the request would be empty.结果我不得不使用 POST 请求,否则请求的正文将为空。

I noticed that you had used async/await in your question, but your answer used promises.我注意到您在问题中使用了 async/await,但您的回答使用了 promise。 I prefer async/await and initially thought that it wasn't supported by Yup for their test function because if your solution, but Yup does support async/await!我更喜欢 async/await,最初认为 Yup 的测试功能不支持它,因为如果您的解决方案,但 Yup 确实支持 async/await! Here's an example of my code for anyone that wants an example.这是我的代码示例,供任何需要示例的人使用。 There are also a few examples in the docs: https://github.com/jquense/yup#mixedtestname-string-message-string--function-test-function-schema文档中还有一些示例: https : //github.com/jquense/yup#mixedtestname-string-message-string--function-test-function-schema

username: Yup.string()
      .min(2, 'Too short, minimum 2 characters')
      .max(50, 'Too long, maximum 50 characters')
      .required('Required')
      .test(
        'username-backend-validation',  // Name
        'Username taken',               // Msg
        async (username) => {
          // Res from backend will be flag at res.data.success, true for 
          // username good, false otherwise
          const { data: { success } } = await axios.post(
            "http://localhost:3001/api/users/register/validate-username", 
            { username: username }
          );

          return success
        }
      )

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

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