Form validation and error handling

User
<script>
import { ref,inject,onMounted } from "vue";
import Google from '@/assets/images/auth/social-google.svg';
import { useAuthStore } from '@/stores/auth';
import { useLoadingStore } from '@/stores/loading';
import { useRouter } from 'vue-router';
import { Form } from 'vee-validate';
import publicApi from '@/publicApi';
const apiUrl = inject('apiUrl');
const loadingStore = useLoadingStore();
const authStore = useAuthStore();
const router = useRouter();
const alertMessage=ref("");
const alertColor=ref("");
const checkbox = ref(false);
const valid = ref(false);
const show1 = ref(false);
//const logform = ref();
const password = ref('');
const username = ref('');
const passwordRules = ref([
  (v: string) => !!v || 'Password is required',
  (v: string) => (v && v.length <= 10) || 'Password must be less than 10 characters'
]);
const emailRules = ref([(v: string) => !!v || 'E-mail is required', (v: string) => /.+@.+..+/.test(v) || 'E-mail must be valid']);

/* eslint-disable @typescript-eslint/no-explicit-any */
const submit = async (values: { email: string; password: string }) => {
    loadingStore.setLoading(true);
    alertMessage.value = "";
    alertColor.value = "";
    try {
        const response = await publicApi.post(`${apiUrl}/login`, {
            email: values.email,  // Use values from VeeValidate
            password: values.password
        });

        console.log(response);
        if (response.data.success) {
            alertMessage.value = "Login successful!";
            alertColor.value = 'success';
            authStore.setUser(response.data.user, response.data.token);
            router.push('/dashboard');
        } else {
            alertMessage.value = response.data.message;
            alertColor.value = 'error';
            console.error("Login failed:", response.data.message);
        }
    } catch (error: any) {
        alertMessage.value = error.response?.data.message;
        alertColor.value = 'error';
        console.error("Error during login:", error.response?.data.message || error.message);
    } finally {
        loadingStore.setLoading(false);
    }
};
</script>

Sign in with Google

OR

Sign in with Email address

Forgot password?

Sign In

{{ errors.apiError }}

Don't Have an account?

<style>
.custom-devider {
  border-color: rgba(0, 0, 0, 0.08) !important;
}
.googleBtn {
  border-color: rgba(0, 0, 0, 0.08);
  margin: 30px 0 20px 0;
}
.outlinedInput .v-field {
  border: 1px solid rgba(0, 0, 0, 0.08);
  box-shadow: none;
}
.orbtn {
  padding: 2px 40px;
  border-color: rgba(0, 0, 0, 0.08);
  margin: 20px 15px;
}
.pwdInput {
  position: relative;
  .v-input__append {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
  }
}
.loginForm {
  .v-text-field .v-field--active input {
    font-weight: 500;
  }
}
</style>

prevent above form submit blank

Assistant
To prevent the form from submitting with blank values, ensure that both `email` and `password` fields are properly validated before submission. You can enforce this in the `submit` function by checking if `values.email` and `values.password` exist before proceeding.

### Fix:
1. Modify the `submit` function to check for empty values.
2. Ensure validation rules are applied correctly.

### Updated `submit` function:

const submit = async (values: { email: string; password: string }) => {
    alertMessage.value = "";
    alertColor.value = "";

    // Prevent submission if fields are empty
    if (!values.email || !values.password) {
        alertMessage.value = "Please fill in all required fields.";
        alertColor.value = 'error';
        return;
    }

    loadingStore.setLoading(true);
    try {
        const response = await publicApi.post(`${apiUrl}/login`, {
            email: values.email,  
            password: values.password
        });

        console.log(response);
        if (response.data.success) {
            alertMessage.value = "Login successful!";
            alertColor.value = 'success';
            authStore.setUser(response.data.user, response.data.token);
            router.push('/dashboard');
        } else {
            alertMessage.value = response.data.message || "Invalid login credentials";
            alertColor.value = 'error';
        }
    } catch (error: any) {
        alertMessage.value = error.response?.data.message || "An error occurred during login.";
        alertColor.value = 'error';
    } finally {
        loadingStore.setLoading(false);
    }
};

### Fix in “:
Ensure that VeeValidate is properly validating the form fields before submission.

<Form @submit="submit" class="mt-7 loginForm" v-slot="{ errors, isSubmitting, values }" :validation-schema="schema">

Define the validation schema:

import * as yup from "yup";

const schema = yup.object({
  email: yup.string().email("Invalid email").required("E-mail is required"),
  password: yup.string().min(6, "Password must be at least 6 characters").required("Password is required"),
});

### Additional Fixes:
– Added a `yup` schema for stricter validation.
– Disabled the submit button if there are errors.

Now, the form will not submit if the email or password fields are empty. Let me know if you need more improvements! 🚀

User
Type '(values: { email: string; password: string; }) => Promise' is not assignable to type 'SubmissionHandler'.
Types of parameters 'values' and 'values' are incompatible.
Type 'GenericObject' is missing the following properties from type '{ email: string; password: string; }': email, passwordts-plugin(2322)
vee-validate.d.ts(1093, 9): The expected type comes from property 'onSubmit' which is declared here on type '__VLS_NormalizeComponentEvent'
Assistant
This TypeScript error occurs because VeeValidate expects a `SubmissionHandler` type, which is more generic than the explicitly typed `(values: { email: string; password: string }) => Promise` function. The solution is to properly type the `submit` function using VeeValidate's expected generic types.

### Solution:
1. Use VeeValidate's `SubmissionHandler` type to ensure compatibility.
2. Update the `submit` function's type to match what VeeValidate expects.

### Updated Code:

Modify the `submit` function:

import { SubmissionHandler } from 'vee-validate';

const submit: SubmissionHandler<{ email: string; password: string }> = async (values) => {
    alertMessage.value = "";
    alertColor.value = "";

    // Prevent submission if fields are empty
    if (!values.email || !values.password) {
        alertMessage.value = "Please fill in all required fields.";
        alertColor.value = 'error';
        return;
    }

    loadingStore.setLoading(true);
    try {
        const response = await publicApi.post(`${apiUrl}/login`, {
            email: values.email,  
            password: values.password
        });

        console.log(response);
        if (response.data.success) {
            alertMessage.value = "Login successful!";
            alertColor.value = 'success';
            authStore.setUser(response.data.user, response.data.token);
            router.push('/dashboard');
        } else {
            alertMessage.value = response.data.message || "Invalid login credentials";
            alertColor.value = 'error';
        }
    } catch (error: any) {
        alertMessage.value = error.response?.data.message || "An error occurred during login.";
        alertColor.value = 'error';
    } finally {
        loadingStore.setLoading(false);
    }
};

Now, update the “ component to ensure it's correctly passing values to `submit`:

<Form @submit="submit" class="mt-7 loginForm" v-slot="{ errors, isSubmitting, values }">

### Why This Works:
– `SubmissionHandler` ensures that the function signature matches VeeValidate’s expectations.
– This prevents TypeScript errors while keeping strong type safety.

Now, your login form should work without TypeScript errors. 🚀

Leave a Comment

Your email address will not be published. Required fields are marked *