Skip to content
Advertisement

How to know if the input is Email or username

I’m trying to let the user sign in using email OR username, I already implemented the backend and it’s working fine using Postman, but I didn’t know how to implement it in the frontend,

Login.jsx:

export default function Login() {
  
  const [credentials, setCredentials] = useState({
      email: undefined,
      username: undefined,
      password: undefined,
    });
  
    const [loginErr, setMsg] = useState({
      fail: false,
      msg: "",

    });
  
    const { user, isFetching, dispatch } = useContext(Context);
  
    const handleChange = (e) => {
      setCredentials((prev) => ({ ...prev, [e.target.id]: e.target.value }));
    };
  
    const handleSubmit = async (e) => {
      e.preventDefault();
      dispatch({ type: "LOGIN_START" });
      try {
        const res = await axios.post("/login", credentials);
        dispatch({ type: "LOGIN_SUCCESS", payload: res.data });
      } catch (err) {
        setMsg({ fail: true, msg: err.response.data.message });
        dispatch({ type: "LOGIN_FAILURE", payload: err.response.data });
      }
    };


    return (

      <div className="login">
  
        {/* LOGIN FORM */}
        <form onSubmit={handleSubmit}>
          <Stack>
            
            <Typography>
            Login to
            </Typography>
  
              {/* Username or Email Address */}
              <Typography variant="h9"
                gutterBottom
                component="div"
                style={{ fontWeight: "bold",
                textAlign: "left"}}
                mt={1}>
            Username or Email Address
            </Typography>
  
          <div class="relative w-full">
              <div class="flex absolute
                      inset-y-0 left-0 items-center pl-3
                      pointer-events-none">
                  <PersonIcon class="w-5 h-5" />
              </div>
                <input type="text"
                className="loginInput"
                style={{ border: loginErr.fail ? '1px solid red' : '' }}
                // ref={userRef}
                name="email"
                id="email"
                onChange={handleChange}/>
          </div>
  
          <button
            className="loginButton"
            type="submit"
            disabled={isFetching}>
  
            {isFetching ? (
                  <CircularProgress size={15}/>
              ) : (
              <Typography
              variant="subtitle2"
              color="white">
                Login
              </Typography>)}
          </button>
  
          </Stack>
        </form>
  
        {/* LOGIN FORM ENDS */}
  
        </div>
    );  
    
  }

My question is how to let the INPUT knows if the user is typing a username or an email and then act accordingly, or is there any easy way to get this done?

Backend Auth.js:

router.post("/login", async (req, res, next) => {
  
  try {

    if (!req.body.password) {
      return next(createError(400, "Invalid password"));
    }

    const user = await User.findOne({$or: [
      {email: req.body.email},
      {username: req.body.username}
    ]});
    if (!user) return next(createError(404, "User not found!"));

    const isPasswordCorrect = await bcrypt.compare(
      req.body.password,
      user.password
    );
    if (!isPasswordCorrect) return next(createError(400, "Wrong password!"));

    const { password, ...others } = user._doc;

    res.status(200).json(others);
  } catch (err) {
    next(err);
  }

});

Advertisement

Answer

So i implemented it on the back-end, I figured out that I don’t have to check if the input is username or an email all I have to do is using $or in the User.findOne it worked like charm here is the code in case of somebody finds it helpful

  const user = await User.findOne({$or: [
  {email: req.body.emailOrUsername},
  {username: req.body.emailOrUsername}
]});

and in the front-end:

  const [credentials, setCredentials] = useState({
      emailOrUsername: undefined,
      password: undefined,
    });

and for the input:

{/* Username or Email Address */}
              <Typography variant="h9"
                gutterBottom
                component="div"
                style={{ fontWeight: "bold",
                textAlign: "left"}}
                mt={1}>
            Username or Email Address
            </Typography>
  
          <div class="relative w-full">
              <div class="flex absolute
                      inset-y-0 left-0 items-center pl-3
                      pointer-events-none">
                  <PersonIcon class="w-5 h-5" />
              </div>
                <input type="text"
                className="loginInput"
                style={{ border: loginErr.fail ? '1px solid red' : '' }}
                // ref={userRef}
                name="emailOrUsername"
                id="emailOrUsername"
                onChange={handleChange}/>
          </div>
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement