Debugging Reset Password Form
March 11, 2025 · AI Conversations
<script>
import { ref, inject, onMounted } from "vue";
import { useForm, useField } from "vee-validate";
import { useAuthStore } from "@/stores/auth";
import { useRouter } from "vue-router";
import publicApi from "@/publicApi";
import SingleColumn from "@/layouts/SingleColumn.vue";
const authStore = useAuthStore();
const router = useRouter();
const apiUrl = inject<string>("apiUrl");
const showPassword = ref(false);
const alertMessage = ref("");
const alertColor = ref("");
const step = ref(1);
const loading = ref(false);
const otp = ref("");
const items = ["Forget Password", "Reset Password"];
onMounted(() => {
if (authStore.isAuthenticated) {
router.push("/dashboard"); // Redirect if already logged in
}
});
// **Email Form Validation**
const { handleSubmit, handleReset } = useForm({
validationSchema: {
email(value: string) {
return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/i.test(value) || "Must be a valid e-mail.";
},
},
});
const email = useField("email");
const password = useField("password");
const confirmPassword = useField("confirmPassword");
const otpField = useField("otp");
// **Password Reset Form Validation**
const { handleSubmit: handleResetSubmit } = useForm({
validationSchema: {
password(value: string) {
return value?.length >= 6 || "Password must be at least 6 characters long.";
},
confirmPassword(value: string) {
return password.value?.value && value === password.value.value || "Passwords do not match.";
}
},
});
// **Submit Forgot Password**
const submit = handleSubmit(async (values) => {
loading.value = true;
alertMessage.value = "";
alertColor.value = "";
try {
const response = await publicApi.post(`${apiUrl}/send-otp-password`, {
email: values.email,
});
loading.value = false;
if (response.data.success) {
alertMessage.value = "OTP has been sent successfully!";
alertColor.value = "success";
step.value = 2;
} else {
alertMessage.value = response.data.message;
alertColor.value = "error";
}
} catch (error: any) {
loading.value = false;
alertMessage.value = error.response?.data.message || "Error sending OTP.";
alertColor.value = "error";
}
});
// **Submit OTP and Reset Password**
const resetPassword = handleResetSubmit(async (values) => {
alert("sfaff")
loading.value = true;
alertMessage.value = "";
alertColor.value = "";
try {
const response = await publicApi.post(`${apiUrl}/verify-otp-password`, {
email: email.value.value,
otp: otp.value,
password: values.password,
confirmPassword: values.confirmPassword,
});
loading.value = false;
if (response.data.success) {
alertMessage.value = "Password reset successfully!";
alertColor.value = "success";
router.push("/login");
} else {
alertMessage.value = response.data.message;
alertColor.value = "error";
}
} catch (error: any) {
loading.value = false;
alertMessage.value = error.response?.data.message || "Error resetting password.";
alertColor.value = "error";
}
});
</script>
Forget Password
Submit
Clear
Reset Password
We sent a verification code to {{ email.value.value || "your email" }}.
Please check your email and paste the code below.
Verify
Didn't receive the code? Resend
when click verify
const resetPassword = handleResetSubmit(async (values) => {
alert("sfaff")
loading.value = true;
alertMessage.value = "";
alertColor.value = "";
try {
const response = await publicApi.post(`${apiUrl}/verify-otp-password`, {
email: email.value.value,
otp: otp.value,
password: values.password,
confirmPassword: values.confirmPassword,
});
loading.value = false;
if (response.data.success) {
alertMessage.value = "Password reset successfully!";
alertColor.value = "success";
router.push("/login");
} else {
alertMessage.value = response.data.message;
alertColor.value = "error";
}
} catch (error: any) {
loading.value = false;
alertMessage.value = error.response?.data.message || "Error resetting password.";
alertColor.value = "error";
}
});
nothing happens
### **Potential Issues & Fixes**
1. **Check if the function is being triggered**
– You added `alert("sfaff")` at the start of `resetPassword`. If the alert is not showing, it means the function is not being called.
– Try adding a `console.log("resetPassword triggered")` inside the function and check the browser console.
2. **Check Form Submission**
– Ensure the `@submit.prevent="resetPassword"` is correctly attached to the form.
– Vue's `useForm()` and `handleSubmit()` return a new function that must be executed. Try updating the form like this:
<form @submit.prevent="resetPassword()">
instead of
<form @submit.prevent="resetPassword">
3. **Check if OTP is Being Collected**
– `otp` is a separate `ref("")`, but you are not binding it to any input field. Add an input field for OTP:
<v-text-field
v-model="otp"
label="OTP"
required
></v-text-field>
4. **Validate API Response**
– Add `console.log(response.data);` inside the `try` block after the API call to inspect the response:
console.log("API Response:", response.data);
5. **Ensure `apiUrl` is Injected**
– `const apiUrl = inject("apiUrl");`
– If `apiUrl` is `undefined`, the API request won't work. Add a check:
console.log("apiUrl:", apiUrl);
6. **Check Console for Errors**
– Open the **browser console** (`F12 > Console`) and check if any Vue or API errors appear.
### **Final Debugging Version**
Modify your `resetPassword` function:
const resetPassword = handleResetSubmit(async (values) => {
console.log("resetPassword triggered");
if (!apiUrl) {
alert("API URL is missing");
return;
}
if (!otp.value) {
alert("OTP is required");
return;
}
loading.value = true;
alertMessage.value = "";
alertColor.value = "";
try {
const response = await publicApi.post(`${apiUrl}/verify-otp-password`, {
email: email.value.value,
otp: otp.value,
password: values.password,
confirmPassword: values.confirmPassword,
});
console.log("API Response:", response.data);
loading.value = false;
if (response.data.success) {
alertMessage.value = "Password reset successfully!";
alertColor.value = "success";
router.push("/login");
} else {
alertMessage.value = response.data.message;
alertColor.value = "error";
}
} catch (error: any) {
loading.value = false;
console.error("API Error:", error.response?.data || error);
alertMessage.value = error.response?.data.message || "Error resetting password.";
alertColor.value = "error";
}
});
### **Summary of Fixes**
✅ Ensure function is actually triggered
✅ Ensure `@submit.prevent="resetPassword()"` in “
✅ Add an OTP input field
✅ Debug API response with `console.log(response.data);`
✅ Verify `apiUrl` is not `undefined`
Try these fixes and let me know what happens! 🚀
<script>
import { ref, inject, onMounted } from "vue";
import { useForm, useField } from "vee-validate";
import { useAuthStore } from "@/stores/auth";
import { useRouter } from "vue-router";
import publicApi from "@/publicApi";
import SingleColumn from "@/layouts/SingleColumn.vue";
const authStore = useAuthStore();
const router = useRouter();
const apiUrl = inject<string>("apiUrl");
const showPassword = ref(false);
const alertMessage = ref("");
const alertColor = ref("");
const step = ref(1);
const loading = ref(false);
const items = ["Forget Password", "Reset Password"];
onMounted(() => {
if (authStore.isAuthenticated) {
router.push("/dashboard"); // Redirect if already logged in
}
});
// **Email Form Validation**
const { handleSubmit, handleReset } = useForm({
validationSchema: {
email(value: string) {
return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/i.test(value) || "Must be a valid e-mail.";
},
},
});
const email = useField("email");
const password = useField("password");
const confirmPassword = useField("confirmPassword");
const otp = useField("otp");
// **Password Reset Form Validation**
const { handleSubmit: handleResetSubmit } = useForm({
validationSchema: {
password(value: string) {
return value?.length >= 6 || "Password must be at least 6 characters long.";
},
confirmPassword(value: string) {
return password.value?.value && value === password.value.value || "Passwords do not match.";
},
otp(value: string) {
return value?.length === 6 || "OTP must be 6 digits.";
},
},
});
// **Submit Forgot Password**
const submit = handleSubmit(async (values) => {
loading.value = true;
alertMessage.value = "";
alertColor.value = "";
try {
const response = await publicApi.post(`${apiUrl}/send-otp-password`, {
email: values.email,
});
loading.value = false;
if (response.data.success) {
alertMessage.value = "OTP has been sent successfully!";
alertColor.value = "success";
step.value = 2;
} else {
alertMessage.value = response.data.message;
alertColor.value = "error";
}
} catch (error: any) {
loading.value = false;
alertMessage.value = error.response?.data.message || "Error sending OTP.";
alertColor.value = "error";
}
});
// **Submit OTP and Reset Password**
const resetPassword = handleResetSubmit(async (values) => {
alert("sfaff")
loading.value = true;
alertMessage.value = "";
alertColor.value = "";
try {
const response = await publicApi.post(`${apiUrl}/verify-otp-password`, {
email: email.value.value,
otp: otp.value,
password: values.password,
confirmPassword: values.confirmPassword,
});
loading.value = false;
if (response.data.success) {
alertMessage.value = "Password reset successfully!";
alertColor.value = "success";
router.push("/login");
} else {
alertMessage.value = response.data.message;
alertColor.value = "error";
}
} catch (error: any) {
loading.value = false;
alertMessage.value = error.response?.data.message || "Error resetting password.";
alertColor.value = "error";
}
});
</script>
Forget Password
Submit
Clear
Reset Password
We sent a verification code to {{ email.value.value || "your email" }}.
Please check your email and paste the code below.
Verify
Didn't receive the code? Resend
click on verify still not work
### Possible Issues:
1. **`otp.value` is an object, not a string**
– You're passing `otp.value` directly in the API request. Since `useField()` returns an object with `.value`, you should use `otp.value.value`.
2. **Fix for OTP field binding**
const response = await publicApi.post(`${apiUrl}/verify-otp-password`, {
email: email.value.value,
- otp: otp.value,
+ otp: otp.value.value,
password: values.password,
confirmPassword: values.confirmPassword,
});
3. **Check for API Errors**
– Add `console.log` to check if the function is executing properly.
4. **Ensure `step` is updating properly**
– Your `resetPassword` form will not trigger unless `step.value === 2`. Double-check if `step.value` is updating after OTP submission.
—
### Debugging Steps:
1. **Check if `resetPassword` is triggered**
Add a `console.log` at the beginning of the `resetPassword` function:
const resetPassword = handleResetSubmit(async (values) => {
console.log("Reset Password function triggered", values);
2. **Verify if API is receiving the right data**
console.log({
email: email.value.value,
otp: otp.value.value,
password: values.password,
confirmPassword: values.confirmPassword,
});
3. **Check for Errors in API Call**
try {
const response = await publicApi.post(`${apiUrl}/verify-otp-password`, {
email: email.value.value,
otp: otp.value.value,
password: values.password,
confirmPassword: values.confirmPassword,
});
console.log("API Response:", response.data);
} catch (error: any) {
console.error("API Error:", error.response?.data);
}
Let me know what you find after adding these logs! 🚀
<script>
import { ref, inject, onMounted } from "vue";
import { useForm, useField } from "vee-validate";
import { useAuthStore } from "@/stores/auth";
import { useRouter } from "vue-router";
import publicApi from "@/publicApi";
import SingleColumn from "@/layouts/SingleColumn.vue";
const authStore = useAuthStore();
const router = useRouter();
const apiUrl = inject<string>("apiUrl");
const showPassword = ref(false);
const alertMessage = ref("");
const alertColor = ref("");
const step = ref(1);
const loading = ref(false);
const items = ["Forget Password", "Reset Password"];
onMounted(() => {
if (authStore.isAuthenticated) {
router.push("/dashboard"); // Redirect if already logged in
}
});
// **Email Form Validation**
const { handleSubmit, handleReset } = useForm({
validationSchema: {
email(value: string) {
return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/i.test(value) || "Must be a valid e-mail.";
},
},
});
const email = useField("email");
const password = useField("password");
const confirmPassword = useField("confirmPassword");
const otp = useField("otp");
// **Password Reset Form Validation**
const { handleSubmit: handleResetSubmit } = useForm({
validationSchema: {
password(value: string) {
return value?.length >= 6 || "Password must be at least 6 characters long.";
},
confirmPassword(value: string) {
return password.value?.value && value === password.value.value || "Passwords do not match.";
},
otp(value: string) {
return value?.length === 6 || "OTP must be 6 digits.";
},
},
});
// **Submit Forgot Password**
const submit = handleSubmit(async (values) => {
loading.value = true;
alertMessage.value = "";
alertColor.value = "";
try {
const response = await publicApi.post(`${apiUrl}/send-otp-password`, {
email: values.email,
});
loading.value = false;
if (response.data.success) {
alertMessage.value = "OTP has been sent successfully!";
alertColor.value = "success";
step.value = 2;
} else {
alertMessage.value = response.data.message;
alertColor.value = "error";
}
} catch (error: any) {
loading.value = false;
alertMessage.value = error.response?.data.message || "Error sending OTP.";
alertColor.value = "error";
}
});
// **Submit OTP and Reset Password**
const resetPassword = handleResetSubmit(async (values) => {
alert("sfaff")
loading.value = true;
alertMessage.value = "";
alertColor.value = "";
try {
const response = await publicApi.post(`${apiUrl}/verify-otp-password`, {
email: email.value.value,
otp: otp.value,
password: values.password,
confirmPassword: values.confirmPassword,
});
loading.value = false;
if (response.data.success) {
alertMessage.value = "Password reset successfully!";
alertColor.value = "success";
router.push("/login");
} else {
alertMessage.value = response.data.message;
alertColor.value = "error";
}
} catch (error: any) {
loading.value = false;
alertMessage.value = error.response?.data.message || "Error resetting password.";
alertColor.value = "error";
}
});
</script>
Forget Password
Submit
Clear
Reset Password
We sent a verification code to {{ email.value.value || "your email" }}.
Please check your email and paste the code below.
Verify
Didn't receive the code? Resend
correct above code
### **Issues & Fixes**
1. **Incorrect `useField` Usage:**
– `useField` should be used inside `useForm`, but you've used it outside.
– **Fix:** Move `useField` inside the respective `useForm` instances.
2. **Incorrect Form Submission:**
– `otp.value`, `password.value.value`, and `confirmPassword.value.value` are accessed incorrectly.
– **Fix:** Use `values` from `handleSubmit`.
3. **Resend OTP Link Issue:**
– You're trying to clear `otp` using `@click.prevent="otp = ''"` directly.
– **Fix:** Use `otp.value.value = ""`.
4. **Alert Debugging (`alert("sfaff")` in `resetPassword`)**
– Remove `alert("sfaff")` from `resetPassword`.
5. **Proper OTP Resend Handling**
– Add an API call for resending OTP.
### **Updated Code**
<script setup lang="ts">
import { ref, inject, onMounted } from "vue";
import { useForm, useField } from "vee-validate";
import { useAuthStore } from "@/stores/auth";
import { useRouter } from "vue-router";
import publicApi from "@/publicApi";
import SingleColumn from "@/layouts/SingleColumn.vue";
const authStore = useAuthStore();
const router = useRouter();
const apiUrl = inject<string>("apiUrl");
const showPassword = ref(false);
const alertMessage = ref("");
const alertColor = ref("");
const step = ref(1);
const loading = ref(false);
const items = ["Forget Password", "Reset Password"];
onMounted(() => {
if (authStore.isAuthenticated) {
router.push("/dashboard"); // Redirect if already logged in
}
});
// **Forgot Password Form Validation**
const { handleSubmit, handleReset } = useForm({
validationSchema: {
email(value: string) {
return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/i.test(value) || "Must be a valid e-mail.";
},
},
});
const email = useField("email");
// **Password Reset Form Validation**
const { handleSubmit: handleResetSubmit } = useForm({
validationSchema: {
password(value: string) {
return value?.length >= 6 || "Password must be at least 6 characters long.";
},
confirmPassword(value: string) {
return password.value?.value && value === password.value.value || "Passwords do not match.";
},
otp(value: string) {
return value?.length === 6 || "OTP must be 6 digits.";
},
},
});
const password = useField("password");
const confirmPassword = useField("confirmPassword");
const otp = useField("otp");
// **Submit Forgot Password**
const submit = handleSubmit(async (values) => {
loading.value = true;
alertMessage.value = "";
alertColor.value = "";
try {
const response = await publicApi.post(`${apiUrl}/send-otp-password`, {
email: values.email,
});
loading.value = false;
if (response.data.success) {
alertMessage.value = "OTP has been sent successfully!";
alertColor.value = "success";
step.value = 2;
} else {
alertMessage.value = response.data.message;
alertColor.value = "error";
}
} catch (error: any) {
loading.value = false;
alertMessage.value = error.response?.data.message || "Error sending OTP.";
alertColor.value = "error";
}
});
// **Submit OTP and Reset Password**
const resetPassword = handleResetSubmit(async (values) => {
loading.value = true;
alertMessage.value = "";
alertColor.value = "";
try {
const response = await publicApi.post(`${apiUrl}/verify-otp-password`, {
email: email.value.value,
otp: values.otp,
password: values.password,
confirmPassword: values.confirmPassword,
});
loading.value = false;
if (response.data.success) {
alertMessage.value = "Password reset successfully!";
alertColor.value = "success";
router.push("/login");
} else {
alertMessage.value = response.data.message;
alertColor.value = "error";
}
} catch (error: any) {
loading.value = false;
alertMessage.value = error.response?.data.message || "Error resetting password.";
alertColor.value = "error";
}
});
// **Resend OTP**
const resendOtp = async () => {
try {
await publicApi.post(`${apiUrl}/send-otp-password`, { email: email.value.value });
alertMessage.value = "OTP has been resent!";
alertColor.value = "success";
} catch (error: any) {
alertMessage.value = "Error resending OTP.";
alertColor.value = "error";
}
};
</script>
<template>
<SingleColumn :md="12" :mt="4">
<OverlayLoading :overlay="loading" />
<v-stepper v-model="step" :items="items" hide-actions>
<!-- Step 1: Enter Email -->
<template v-slot:item.1>
<v-card class="py-8 px-6 text-center mx-auto ma-4" elevation="12" max-width="600">
<h3 class="text-h6 mb-4">Forget Password</h3>
<v-sheet class="mx-auto mt-4 mb-4" max-width="600">
<form @submit.prevent="submit">
<v-text-field
v-model="email.value.value"
:error-messages="email.errorMessage.value"
label="E-mail"
></v-text-field>
<v-btn class="me-4" type="submit"> Submit </v-btn>
<v-btn @click="handleReset"> Clear </v-btn>
</form>
</v-sheet>
</v-card>
</template>
<!-- Step 2: OTP Verification & Password Reset -->
<template v-slot:item.2>
<v-card class="py-8 px-6 text-center mx-auto ma-4" elevation="12" max-width="400">
<h3 class="text-h6 mb-4">Reset Password</h3>
<div class="text-body-2">
We sent a verification code to {{ email.value.value || "your email" }}. <br />
Please check your email and paste the code below.
</div>
<v-sheet color="surface">
<form @submit.prevent="resetPassword">
<v-text-field
v-model="otp.value.value"
:error-messages="otp.errorMessage.value"
label="OTP"
required
></v-text-field>
<v-text-field
v-model="password.value.value"
:type="showPassword ? 'text' : 'password'"
:error-messages="password.errorMessage.value"
prepend-inner-icon="mdi-lock"
:append-inner-icon="showPassword ? 'mdi-eye-off' : 'mdi-eye'"
@click:append-inner="showPassword = !showPassword"
label="Password"
></v-text-field>
<v-text-field
v-model="confirmPassword.value.value"
:type="showPassword ? 'text' : 'password'"
:error-messages="confirmPassword.errorMessage.value"
prepend-inner-icon="mdi-lock"
:append-inner-icon="showPassword ? 'mdi-eye-off' : 'mdi-eye'"
@click:append-inner="showPassword = !showPassword"
label="Confirm Password"
></v-text-field>
<v-btn class="my-4" color="purple" height="40" variant="flat" type="submit" width="70%">
Verify
</v-btn>
<div class="text-caption">
Didn't receive the code?
<a href="#" @click.prevent="resendOtp">Resend</a>
</div>
</form>
</v-sheet>
</v-card>
</template>
</v-stepper>
<TheAlert v-if="alertMessage" :title="alertMessage" :color="alertColor" :icon="alertColor" />
</SingleColumn>
</template>
### **Key Fixes**
✅ Moved `useField` inside `useForm` correctly.
✅ Fixed `otp.value` access.
✅ Implemented proper OTP resend functionality.
✅ Removed debugging `alert("sfaff")`.
This should now work without errors. 🚀