VeeValidate3: Unique validation will always return true upon submission

I have integrated Vue.js 2 and VeeValidate3 to validate my form. In addition, the form makes an axios call to verify if the username is already in use. If it is, the validation should be set to false.

Everything seems to be working fine so far. I am able to see the error message

Dieser Name wird bereits verwendet
when I enter a username that is already taken.

However, I noticed that if I proceed to click the submit button despite seeing the error message, the error message disappears and instead, I see the message

Submit submitCompleteNormalRegistrationForm
indicating that the form was successfully submitted.

This raises the question as to why the form gets submitted even with a validation error regarding the name. What mistake am I making?

Furthermore, how can I ensure that the validation for the name is set to true when the name is not already in use?

Below is the code I currently have:

<template>
    <div>
        <ValidationObserver ref="completeNormalRegistrationForm" v-slot="{ passes }" class="flex-column flex-grow-1 d-flex w-100">
            <form @submit.prevent="passes(submitCompleteNormalRegistrationForm)" id="completeNormalRegistrationForm" class="flex-column flex-grow-1 d-flex w-100">
                <div class="backButtonWrapper text-left">
                    <i id="backButtonRegistrationForm" @click="showLoginForm" class="far fa-arrow-alt-circle-left"></i>
                </div>
                <div class="form-wrapper margin-auto w-100">
                    <p class="rubik-bold" style="font-size: 1rem;">Registrieren</p>
                    <ValidationProvider vid="name" name="Nutzername" rules="required|alpha_dash" v-slot="{ errors }">
                        <input @keyup="completeNormalRegistrationFormUsernameExists" class="form-control search-username" v-model="registerForm.name" type="text" placeholder="Username">
                        <span v-if="errors[0]" class="username-invalid-span">{{ errors[0] }}</span>
                    </ValidationProvider>
                    <ValidationProvider vid="email" name="E-Mail" rules="required|email" v-slot="{ errors }">
                        <input class="form-control search-email" v-model="registerForm.email" type="email" placeholder="E-Mail">
                        <span v-if="errors[0]" class="email-invalid-span">{{ errors[0] }}</span>
                    </ValidationProvider>
                    <ValidationProvider vid="confirmation" name="Passwort" v-slot="{ errors }">
                        <input class="form-control" v-model="registerForm.password" type="password" placeholder="Passwort">
                        <span v-if="errors[0]" class="password-invalid-span">{{ errors[0] }}</span>
                    </ValidationProvider>
                    <ValidationProvider rules="confirmed:confirmation" name="Passwort" v-slot="{ errors }">
                        <input class="form-control" v-model="registerForm.passwordConfirmation" type="password" placeholder="Passwort wiederholen">
                        <span v-if="errors[0]" class="password-invalid-span">{{ errors[0] }}</span>
                    </ValidationProvider>

                    <button type="submit" class="btn btn-primary btn-big big-letter-spacing text-uppercase rubik-bold login">Anmelden</button>
                </div>
            </form>
        </ValidationObserver>
    </div>
</template>

<script>
    export default {
        name: "NavbarAction",
        data() {
            return {
                registerForm: {
                    name: '',
                    email: '',
                    password: '',
                    passwordConfirmation: '',
                    termsAndConditions: false,
                },
            }
        },
        methods: {
            async completeNormalRegistrationFormUsernameExists() {
                const nameValid = await this.usernameExists(this.registerForm.name);

                if (nameValid) {
                    this.$refs.completeNormalRegistrationForm.setErrors({name: 'Dieser Name wird bereits verwendet'});
                } else {
                    console.log('Set name is NOT in use!');
                }
            },
            async usernameExists(name){
                return await axios.post(window.routes.usernameExists, {value: name})
                    .then(r => {
                        return r.data;
                    });
            },
            submitCompleteNormalRegistrationForm(){
                console.log('Submit submitCompleteNormalRegistrationForm');
                console.log(this);
            }
        }
    }
</script>

UPDATE (now utilizing custom rule):

extend('unique-email', (value) => {
    return axios.post(this.routes.emailExists, { value: value })
        .then((r) => {

            // If email exists, axios response is true
            if(r.data){
                return {
                    valid: false,
                    data: { message: 'E-Mail wird bereits genutzt' }
                };
            }else{
                return {
                    valid: true,
                };
            }
        }, (err) => {
            return {
                valid: false,
                data: { message: 'E-Mail wird bereits genutzt' }
            };
        })
    },
)

Answer №1

If you want to validate email using vee-validate, it's better to define it as a rule instead of manually handling it on keyup event. An interesting feature of vee-validate is that if a promise is returned as the result of validation, vee-validate will handle it properly by waiting for the resolution before validating.

See below for an example:

 mounted() {
   extend('unique-email', (value) => {
     return this.usernameExists(value)
     .then((res) => {
      return {
        valid: true,
      };
    }, (err) => {
      this.$refs.completeNormalRegistrationForm.setErrors({
         name: ['Username already registered']
      });
    })
    }, {
     immediate: false
   })
 }

Answer №2

When it comes to front-end validation, the main action you can take is deactivating the button if the form is not valid. However, this approach does not prevent a knowledgeable individual from attempting to submit the form regardless. For thorough validation and security, server-side validation is crucial.

For instance:

<button type="submit" class="btn btn-primary btn-big big-letter-spacing text-uppercase rubik-bold login" :disabled="passes(submitCompleteNormalRegistrationForm)">Anmelden</button>

Answer №3

At last, I've discovered a method to customize error messages without relying on $refs:

extend('unique-email', (value) => {
    return axios.post(window.laravel.emailExists, { value: value })
        .then((r) => {

            // If the email already exists, axios response will be true
            if(r.data){
                return "Email is already in use";
            }else{
                return true;
            }
        }, (err) => {
            return "Email is already in use";
        })
    },
);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilize HTML5 and JavaScript to calculate the velocity of a device by employing devicemotion and device

Can device speed in km/h be calculated using the devicemotion/deviceorientation HTML5 API? I am interested in determining whether a user is walking, running, or stationary without relying on the geolocation API, which may not be accurate indoors. ...

storing audio files locally with Vue.js

Looking for a way to store a sound locally for my Battleship game rather than referencing it on the internet. Here's the code that triggers the sound: @click.prevent="fireSound('http://soundbible.com/grab.php?id=1794&type=mp3')" I atte ...

Combining items with nested Map structures

I am in need of merging multiple JavaScript objects recursively. These objects contain number properties that need to be added together during the merge process. Additionally, they also have Map properties. Below is an example of how my object appears in t ...

Include quotation marks around a string in C# to convert it into JSON format

I am utilizing a service that operates with JSON format. However, the JSON data I am receiving does not include double quotes around keys and values. Here is an example of the data I have: [{name:{buyerfirstname:Randy, buyermiddlename:null, buyerlastnam ...

The sticky navigation bar unexpectedly jerks and creates a glitch

For the past few days, I've been grappling with a persistent issue that seems to be causing glitches on my site, especially when viewed on my iPhone. The problem lies in the sticky navbar, which snaps to the wrong place and jumps too fast when scrolli ...

Creating a customized greeting message using discord.js

I've been working on creating a Discord bot using discord.js, and I'm trying to figure out how to make the bot send a welcome message when a new member joins the server and opens a chat with the bot. The message should be something like "Hi there ...

Set a timer to run only during particular hours of the day, and pause until the next designated time

I need assistance with integrating a function called "tweeter" into my code so that it runs at specific times throughout the day - 09:00, 13:00, 17:00, and 21:00. Currently, the function runs continuously after the initial hour check is completed, instead ...

What is the best way to adjust the placement of a component to remain in sync with the v-model it is connected to?

I am encountering an issue with 2 sliders in my project. I have set it up so that when the lower slider's value is greater than 0, the top slider should automatically be set to 5. I am using a watcher function for this purpose. However, if I manually ...

Is web analytics done via client-side (JavaScript) or server-side logging on websites?

As I embark on creating a web application to track web statistics for my clients, I've run into a dilemma. With the rise of ajax usage, I'm unsure whether it's best to log a user visit using JavaScript or serverside. Additionally, I'm u ...

Conditional statements in jQuery for identifying a specific div based on its id

My current setup involves an HTML table that gets populated based on a mysql query. The table is enclosed within: <div id="punchclock" class="timecard"> I also have a jQuery script in place to calculate the totals of the times entered into this tab ...

Executing PHP scripts using Ajax

Check out the code snippet below: <?php //echo $this->Html->css(array('bootstrap', 'mark', 'style')); echo $this->Html->script(array('timer','swfobject','bootstrap.min.js')); // ...

Generating interactive sound using Node.js

Issue My current application, a morse code translator, is experiencing difficulties in playing multiple sounds for user input. It seems that only a single sound is played even when the method is called multiple times. Additionally, the sound is being play ...

VueJS - Issue with assigning values from mapState to data property upon page reload

When reloading the page, it seems like the value from mapState cannot be assigned to the data property. Strangely, it works if you navigate to the child page, but not if you are already on the child page and refresh the browser. Using Computed mapState c ...

What is the best way to incorporate a toggle hamburger animation into the mobile menu using WordPress and JavaScript?

Looking to add a toggle hamburger animation to my mobile menu on WordPress. I tried following a tutorial where the JavaScript code had separate "Open" and "Close" buttons as icons. Although I have a hamburger menu, I'm struggling with understanding ho ...

Securing your Angular application with user authentication and route guarding ensures

In the process of developing an Angular single-page application (SPA) front-end that interacts with a GraphQL endpoint, I encountered a challenge. Upon user login, I store the token in local storage and update the authentication state in my AuthService com ...

Load HighCharts dynamically in a sequential manner

Currently, I am working on dynamically loading a variety of series based on user-selected projects. My tech stack includes Laravel 5.2, PHP 5.6, and HighCharts. I've successfully loaded one JSON file generated upon project selection. However, I aim to ...

Closing tag in jQuery

In my script, I am using a div tag within the jquery code. However, whenever the div tag appears in the jquery code, it automatically closes the script tag and breaks the jquery code. For example, consider the following code: <script>var b = 25;var ...

Error message 'MODULE_NOT_FOUND' occurs while executing a Docker application

Although I successfully created a docker image, I am encountering issues when trying to run it. This is the command that I am using for running: docker run coderpc/test-server Displayed below is the error message that appears in the console. Error: Canno ...

The Prime Vue Tooltip appears beneath various components

I'm facing an issue with Prime Vue's v-tooltip.top where the tooltips are appearing under other divs instead of on top. I've attempted to use :deep in the CSS without success. Is there a way to adjust the z-index or is there a different solu ...

In search of a JavaScript library that can help format strings to meet the requirements of JSON formatting

Utilizing jQuery ajax, I am transmitting updates from the client's browser to my server. However, I have noticed that there are certain characters not supported by JSON that require an additional "\" in front of each one to be properly sent. The ...