MERN stack Forget Password doesn't work on frontend (Postman works perfectly fine). when put the email and click the send button then showing this error - user not found I'm trying but I can't solve the problem. Please give me some advice.
userController.js
const ErrorHandler = require("../utils/errorHandler");
const catchAsyncErrors = require("../middleware/catchAsyncError");
const User = require('../models/userModel');
const sendEmail = require("../utils/sendMail")
exports.forgotPassword = catchAsyncErrors(async (req, res, next) => {
const user = await User.findOne({email: req.body.email});
if (!user) {
return next(new ErrorHandler("User not found", 404));
}
const resetToken = user.getResetPasswordToken();
await user.save({ validateBeforeSave: false });
const resetPasswordUrl =`${req.protocol}://${req.get("host")}/api/v1/password/reset/${resetToken}`;
const message = `Your password reset token is :- \n\n ${resetPasswordUrl} \n\nIf you have not requested this email then, please ignore it.`;
try {
await sendEmail({
email: user.email,
subject: `Ecommerce Password Recovery`,
message,
});
res.status(200).json({
success: true,
message: `Email sent to ${user.email} successfully`,
});
} catch (error) {
user.resetPasswordToken = undefined;
user.resetPasswordExpire = undefined;
await user.save({ validateBeforeSave: false });
return next(new ErrorHandler(error.message, 500));
}
});
userRoute.js
const express = require("express");
const router = express.Router();
const {forgotPassword} = require("../controllers/userController");
router.route("/password/forgot").post(forgotPassword);
app.js
const user = require('./routes/userRoute');
app.use('/api/v1',user);
userConstant.js
export const FORGOT_PASSWORD_REQUEST = "FORGOT_PASSWORD_REQUEST";
export const FORGOT_PASSWORD_SUCCESS = "FORGOT_PASSWORD_SUCCESS";
export const FORGOT_PASSWORD_FAIL = "FORGOT_PASSWORD_FAIL";
export const CLEAR_ERRORS ="CLEAR_ERRORS";
userReducer.js
import {
FORGOT_PASSWORD_REQUEST,
FORGOT_PASSWORD_SUCCESS,
FORGOT_PASSWORD_FAIL,
CLEAR_ERRORS
} from "../constants/userConstant";
export const forgotPasswordReducer = (state = {}, action) => {
switch (action.type) {
case FORGOT_PASSWORD_REQUEST:
return {
...state,
loading: true,
error: null,
};
case FORGOT_PASSWORD_SUCCESS:
return {
...state,
loading: false,
message: action.payload,
};
case FORGOT_PASSWORD_FAIL:
return {
...state,
loading: false,
error: action.payload,
};
case CLEAR_ERRORS:
return {
...state,
error: null,
};
default:
return state;
}
};
userAction.js
import {
FORGOT_PASSWORD_REQUEST,
FORGOT_PASSWORD_SUCCESS,
FORGOT_PASSWORD_FAIL,
CLEAR_ERRORS
} from "../constants/userConstant";
export const forgotPassword = (email) => async (dispatch) => {
try {
dispatch({ type: FORGOT_PASSWORD_REQUEST });
const { data } = await axios.post(`/api/v1/password/forgot`, email);
dispatch({ type: FORGOT_PASSWORD_SUCCESS, payload: data.message });
} catch (error) {
dispatch({
type: FORGOT_PASSWORD_FAIL,
payload: error.response.data.message,
});
}
};
ForgotPassword.js
import React, { Fragment, useState, useEffect } from "react";
import "./ForgetPassword.css";
import Loader from "../Loader/Loader";
import { useDispatch, useSelector } from "react-redux";
import { clearErrors, forgotPassword } from "../../actions/userAction";
const ForgetPassword = () => {
const dispatch = useDispatch();
const { error, message, loading } = useSelector(
(state) => state.forgotPassword
);
const [email, setEmail] = useState("");
const forgotPasswordSubmit = (e) => {
e.preventDefault();
const myForm = new FormData();
myForm.set("email", email);
dispatch(forgotPassword(myForm));
};
useEffect(() => {
if (error) {
alert(error);
dispatch(clearErrors());
}
if (message) {
alert(message);
}
}, [dispatch, error, message]);
return (
<Fragment>
{loading ? (
<Loader />
) : (
<Fragment>
<div className="forgotPasswordContainer">
<form className="forgotPasswordForm" onSubmit={forgotPasswordSubmit}>
<h2 className="forgotPasswordHeading">Forgot Password</h2>
<input className="inputsignforgot" type="email" placeholder="Email" required name="email"
value={email} onChange={(e) => setEmail(e.target.value)} />
<input type="submit" value="Send" className="forgotPasswordBtn" />
</form>
</div>
</Fragment>
)}
</Fragment>
);
};
export default ForgetPassword;
App.js
import ForgotPassword from './components/Users/ForgotPassword';
<Route path='/password/forgot' exact element={<ForgotPassword/>} />
CodePudding user response:
Try to change the dispatch
call to accept the email as a parameter in ForgotPassword
(as @AndrewAllison suggested):
const forgotPasswordSubmit = (e) => {
e.preventDefault();
dispatch(forgotPassword(email));
};
Also, change your axios
call to send the body parameter as an object:
export const forgotPassword = (email) => async (dispatch) => {
try {
dispatch({ type: FORGOT_PASSWORD_REQUEST });
// Send body param as object
const { data } = await axios.post(`/api/v1/password/forgot`, { email });
dispatch({ type: FORGOT_PASSWORD_SUCCESS, payload: data.message });
} catch (error) {
dispatch({
type: FORGOT_PASSWORD_FAIL,
payload: error.response.data.message,
});
}
};