1
votes

I have a custom validation in VeeValidate for EU Vat Numbers. It connects to our API, which routes it to the VIES webservice. This webservice is very unstable though, and a lot of errors occur, which results in a 500 response. Right now, I return false when an error has occured, but I was wondering if there was a way to warn the user that something went wrong instead of saying the value is invalid?

Validator.extend('vat', {
  getMessage: field => 'The ' + field + ' is invalid.',
  validate: async (value) => {
    let countryCode = value.substr(0, 2)
    let number = value.substr(2, value.length - 2)
    try {
        const {status, data} = await axios.post('/api/euvat', {countryCode: countryCode, vatNumber: number})
        return status === 200 ? data.success : false
    } catch (e) {
        return false
    }
  },
}, {immediate: false})

EDIT: Changed code with try-catch.

4

4 Answers

1
votes

You can use:

try {
  your logic
}
catch(error) {
  warn user if API brokes (and maybe inform them to try again)
}
finally {
 this is optional (you can for example turn of your loader here)
}

In your case try catch finally block would go into validate method

1
votes

OK, first of all I don't think that informing user about broken API in a form validation error message is a good idea :-| (I'd use snackbar or something like that ;) )

any way, maybe this will help you out:

I imagine you are extending your form validation in created hook so maybe getting message conditionaly to variable would work. Try this:

 created() {
+  let errorOccured = false;
   Validator.extend('vat', {
-    getMessage: field => 'The ' + field + ' is invalid.',
+    getMessage: field => errorOccured ? `Trouble with API` : `The ${field} is invalid.`,
     validate: async (value) => {
       let countryCode = value.substr(0, 2)
       let number = value.substr(2, value.length - 2)
       const {status, data} = await axios.post('/api/euvat', {countryCode: countryCode, vatNumber: number})
+      errorOccured = status !== 200;
       return status === 200 ? data.success : false;
     },
   }, {immediate: false})
 }
1
votes

After searching a lot, I found the best approach to do this. You just have to return an object instead of a boolean with these values:

{
  valid: false,
  data: { message: 'Some error occured.' }
}

It will override the default message. If you want to return an object with the default message, you can just set the data value to undefined.

0
votes

Here is a veeValidate v3 version for this:

import { extend } from 'vee-validate';

extend('vat', async function(value) {

    const {status, data} = await axios.post('/api/validate-vat', {vat: value})
    if (status === 200 && data.valid) {
        return true;
    }
    
    return 'The {_field_} field must be a valid vat number';
});

This assumes your API Endpoint is returning json: { valid: true } or { valid: false }