Home > other >  Error in PUT API request in reactJS fetch from frontend
Error in PUT API request in reactJS fetch from frontend

Time:12-29

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.

CodePudding user response:

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,
    }
});

CodePudding user response:

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,
      }),
    });

  • Related