0

I have a login form at the client side (react) that I try to submit and pass the credentials to the login function at the server side (node.js)

when I use postman to send raw json object with the user name and password it works fine, but when I sent it through the client side the req.body contains only this: [[Prototype]]: Object

what am I doing wrong here?

here is the code of the component that contains the form:

import React from 'react';
import '../signIn/signIn.component.css'
import { Link } from "react-router-dom";
import { useState, useEffect } from "react";

export default function SignIn() {
    const [UserName, setUsername] = useState(null);
    const [PassWord, setPassWord] = useState(null);
    const [FormData, setFormData] = useState({});

    useEffect(() => {
        setFormData({ UserName: UserName, PassWord: PassWord });
    }, []);

    const submitFormSignIn = () => {
        const testURL = "http://localhost:3100/login";
        const myInit = {
            method: "POST",
            mode: 'no-cors',
            body: JSON.stringify(FormData),
            headers: {
                'Content-Type': 'application/json'
            },
        };
        const myRequest = new Request(testURL, myInit);
        fetch(myRequest).then(function (response) {
            return response;
        }).then(function (response) {
            console.log(response);
        }).catch(function (e) {
            console.log(e);
        });
    }

    return (
        <React.Fragment>
            <form onSubmit={(e) => { submitFormSignIn(); e.preventDefault(); }}>
                <div className="signIn-form-container">
                    <h1 className="welcome-header">Welcome</h1>
                    <div className="userName-form-container">
                        <input className="input-user-name" type="text" name="userName" placeholder='User name'
                            //should start with an alphabet so. All other characters can be alphabets, numbers or an underscore so.
                            required
                            pattern="^[A-Za-z][A-Za-z0-9_]{7,29}$"
                            minLength={"6"}
                            maxLength={"20"}
                            onChange={(e) => setUsername(e.target.value)}
                        ></input>
                    </div>
                    <div className="password-form-container">
                        <input className="input-password" type="password" name="passWord" required
                            //Minimum eight characters, at least one uppercase letter, one lowercase letter and one number:
                            pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$"
                            autoComplete="on"
                            minLength={"9"}
                            maxLength={"20"}
                            placeholder='Password'
                            onChange={(e) => setPassWord(e.target.value)}
                        ></input>
                    </div>
                    <div className="forgot-remember-container">
                        <Link className="userName-forgot-link" to="/userNameRecovery">Forgot user name?</Link>
                        <Link className="password-forgot-link" to="/passwordRecovery">Forgot password?</Link>
                    </div>
                    <div className="form-submit-btn-container">
                        <button className="form-submit-btn">Sign in</button>
                    </div>
                    <div className="sign-up-container">
                        <a>Don't have an account?</a>
                        <Link className="signUp-link" to="/register">Sign up</Link>
                    </div>
                    <hr></hr>
                </div>
            </form>
        </React.Fragment>
    );
}

2 Answers 2

1

Your useEffect is fired only once - after initial render, because it's dependency array is empty. It means, you don't set for formData state with proper data.

I see two solutions: Either fill the dependency array with UserName and PassWord states:

useEffect(() => {
        setFormData({ UserName: UserName, PassWord: PassWord });
    }, [UserName, PassWord]);

Or - and I would recommend this - easily create your body Object directly from UserName and PassWord states to :

body: JSON.stringify({UserName, PassWord}),

Small underline notice: states are variables, so their name should be camelCase, with lowercase at the beginning. Variables with UpperCase are intended to be React Components.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks, I used you're recommendations but what solved the issue for me is that for some reason "no-cors" messed the req.body so I used "cors" but it made me handle the cors at the sever side and now it works.
0

useEffect in this case absolutely unnecessary, so you have both and submit handler and useEffect that actually make you app rerender several extra times through setState, so Id build this something like that

import React from 'react';
import '../signIn/signIn.component.css'
import { Link } from "react-router-dom";
import { useState } from "react";

export default function SignIn() {
    const [username, setUsername] = useState(null);
    const [password, setPassword] = useState(null);

    const submitFormSignIn = () => {
        const testURL = "http://localhost:3100/login";
        const myInit = {
            method: "POST",
            mode: 'no-cors',
            body: JSON.stringify({ username, password }),
            headers: {
                'Content-Type': 'application/json'
            },
        };
        const myRequest = new Request(testURL, myInit);
        fetch(myRequest).then(function (response) {
            return response;
        }).then(function (response) {
            console.log(response);
        }).catch(function (e) {
            console.log(e);
        });
    }

    return (
        <React.Fragment>
            //same jsx
        </React.Fragment>
    );
} 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.