0

I am making a PUT request to change the password of a user, here I am using reactJS in the frontend and express+mongoDB in the backend (MERN). The API is working fine in the backend.

My API body + successful response (using backend only)

enter image description here

But when I make the frontend page and make the fetch request, I am getting this error in the backend terminal.

Illegal arguments: undefined, string

frontEnd code

import React, {useState} from "react";
import { useNavigate } from "react-router-dom";

const ChangePasswordPage = (props) => {
  let navigate = useNavigate();

  const [showPassword, setShowPassword] = useState(false);
  const [showConfmPassword, setShowConfmPassword] = useState(false);

  const [newCredentials, setNewCredentials] = useState({
    email: "",
    newPassword: "",
    confmNewPassword: "",
  });

  const onChange = (e) => {
    setNewCredentials({
      ...newCredentials,
      [e.target.name]:e.target.value,
    });
  };

  console.log(newCredentials);

  const handleSubmit = async (e) => {
    e.preventDefault();
    const response = await fetch("http://localhost:5000/api/changePassword",{
      method:"PUT",
      body: JSON.stringify({
        email: newCredentials.email,
        newPassword: newCredentials.newPassword,
        confmNewPassword: newCredentials.confmNewPassword,
      }),
    });

    const json = await response.json();
    console.log(json)

    if(json.success === true) {
      localStorage.setItem("token", json.authToken);
      props.showAlert("Password Changed Successfully !", "info");
      navigate("/login");
    } 
    else {
      props.showAlert("Password Did Not Changed", "danger")
    }
  }

  const backToForgot = () => {
    navigate("/forgotPassword");
  }

  function togglePasswordVisibilty() {
    setShowPassword(!showPassword ? true : false);
  }

  function toggleConfmPasswordVisibilty() {
    setShowConfmPassword(!showConfmPassword ? true : false);
  }


  return (
<>
      <div className="container my-3">
        <div
          id="loginbody"
          style={{ backgroundColor: "gainsboro", padding: "5%" }}
        >
          <div className="mt-3">
            <h2 className="my-3 display-3">Change Password</h2>
            <form className="login-form p-5" onSubmit={handleSubmit}>
              <div className="mb-3">
                <label htmlFor="exampleInputEmail1" className="form-label">
                  Email address
                </label>
                <input
                  type="email"
                  className="form-control"
                  id="email"
                  name="email"
                  value={newCredentials.email}
                  aria-describedby="emailHelp"
                  onChange={onChange}
                />
                <div id="emailHelp" className="form-text">
                  Type email again to ensure your identity.
                </div>
              </div>

              <div className="mb-3">
                <div
                  className="pass-wrapper"
                  style={{ display: "flex", alignItems: "center" }}
                >
                  <label
                    htmlFor="newPassword"
                    className="form-label"
                    style={{ width: "200px" }}
                  >
                    New Password
                  </label>
                  <div
                    style={{
                      border: "1px solid #ced4da",
                      display: "flex",
                      alignItems: "center",
                      width: "100%",
                    }}
                  >
                    <input
                      type={showPassword ? "text" : "password"}
                      className="form-control mx-3"
                      id="newPassword"
                      name="newPassword"
                      minLength={5}
                      value={newCredentials.newPassword}
                      onChange={(e) => onChange(e, "newPassword")}
                      style={{ outline: "none", border: 0 }}
                      required
                    />
                    <i
                      className={
                        showPassword
                          ? "fas fa-eye-slash mx-2"
                          : "fas fa-eye mx-2"
                      }
                      title={showPassword ? "Hide New Password" : "Show New Password"}
                      onClick={togglePasswordVisibilty}
                    ></i>
                  </div>
                </div>
              </div>

              <div className="mb-3">
                <div
                  className="pass-wrapper"
                  style={{ display: "flex", alignItems: "center" }}
                >
                  <label
                    htmlFor="confmNewPassword"
                    className="form-label"
                    style={{ width: "200px" }}
                  >
                    Confirm New Password
                  </label>
                  <div
                    style={{
                      border: "1px solid #ced4da",
                      display: "flex",
                      alignItems: "center",
                      width: "100%",
                    }}
                  >
                    <input
                      type={showConfmPassword ? "text" : "password"}
                      className="form-control mx-3"
                      id="confmNewPassword"
                      name="confmNewPassword"
                      value={newCredentials.confmNewPassword}
                      onChange={(e) => onChange(e, "confmNewPassword")}
                      minLength={5}
                      required
                      style={{ border: 0, outline: "none" }}
                    />
                    <i
                      className={
                        showConfmPassword
                          ? "fas fa-eye-slash mx-2"
                          : "fas fa-eye mx-2"
                      }
                      title={
                        showConfmPassword
                          ? "Hide Confirmed NewPassword"
                          : "Show Confirmed NewPassword"
                      }
                      onClick={toggleConfmPasswordVisibilty}
                    ></i>
                  </div>
                </div>
              </div>

              <div className="d-grid gap-2 my-4 col-6 mx-auto">
                <button
                  type="submit"
                  className="btn btn-primary col-6 m-auto my-2"
                >
                  Change Password
                </button>
              </div>
              <hr />
              <div className="mb-3 text-center">
                <div id="emailHelp" className="form-text center my-3">
                  Want to go back ?
                </div>
                <div className="d-grid gap-2 my-3 col-6 mx-auto">
                  <button
                    onClick={backToForgot}
                    className="btn btn-primary col-6 m-auto"
                  >
                    Back
                  </button>
                </div>
              </div>
            </form>
          </div>
        </div>
      </div>
    </>
  );
};

export default ChangePasswordPage;

backEnd code

const express = require("express");
const router = express.Router();
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const JWT_SECRET = "mohitisagood$boy";
const User = require("../models/User");

router.put("/", async (req, res) => {
  const { email, newPassword, confmNewPassword } = req.body;

  let success = false;

  try {
    //hashing the new password
    const salt = await bcrypt.genSalt(10);
    const secPass = await bcrypt.hash(newPassword, salt);

    //if newpassword does not matche swoth confirmPassword
    if (newPassword !== confmNewPassword) {
      res.status(400).json({ success, error: "Both password did not match !" });
    }

    //updating password
    let user = await User.findOneAndUpdate(
      { email: email },
      { $set: { password: secPass } },
      { returnOriginal: false }
    );

    if (!user) {
      res.status(400).json({ success, error: "Email does not exists !" });
    }

    //console.log(user);

    const payload = {
      user: {
        id: user.id,
      },
    };

    const authToken = jwt.sign(payload, JWT_SECRET);

    success = true;

    res.json({ success, authToken, user });
  } catch (error) {
    console.log(error.message);
    res.status(500).send("Internal Server Error");
  }
});

module.exports = router;

I have consoled the newCredentials at frontEnd and it give this

console

Then after the line console.log(json) in the frontEnd code is not working. It means that the error comes in the fetch part only.

Please throw your light of knowledge and solve the issue.

1
  • Its for input on the UI Commented Dec 28, 2021 at 12:16

2 Answers 2

1

Remove the JSON.stringify

const response = await fetch("http://localhost:5000/api/changePassword", {
    method: "PUT",
    headers: {
        Accept: "application/json",
    },
    body: {
        email: newCredentials.email,
        newPassword: newCredentials.newPassword,
        confmNewPassword: newCredentials.confmNewPassword,
    }
});
Sign up to request clarification or add additional context in comments.

6 Comments

Not working, still showing same error. @Narendra Chouhan
try to add headers in the fetch api call, please check the updated code @MohitMaroliyaB17CS036
Okay but before I added the headers. it was showing error Cannot set headers after they are sent to the client
Your backend API is sending two-time res, try to debug or comment all the res and keep only one res. send()
just try to add return res.status(400).json() "return" in front of the response's you are sending @MohitMaroliyaB17CS036
|
1

I corrected the code by adding the header

const handleSubmit = async (e) => {
    e.preventDefault();
    const response = await fetch("http://localhost:5000/api/changePassword",{
      method:"PUT",
      content: "application/json",
      body: JSON.stringify({
        email: newCredentials.email,
        newPassword: newCredentials.newPassword,
        confmNewPassword: newCredentials.confmNewPassword,
      }),
    });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.