0

I have 5 different inputs for taking OTP. and I am using 6 useState hook to get their value.

Now I want to store those 5 input value in the 6th variable I'm passing to my redux store.
I tried this way but it returns an object and also use parseInt but it doesn't work.

  const [otp, setOtp] = useState(null);
  const [digitOne, setDigitOne] = useState(null);
  const [digitTwo, setDigitTwo] = useState(null);
  const [digitThree, setDigitThree] = useState(null);
  const [digitFour, setDigitFour] = useState(null);
  const [digitFive, setDigitFive] = useState(null);

  const handleSubmit = (e) => {
    e.preventDefault();
    const otp = { digitOne, digitTwo, digitThree, digitFour, digitFive };
    console.log(digitOne, digitTwo, digitThree, digitFour, digitFive);
    dispatch(checkVerification({ user_info, otp })).then(() => {
      console.log(otp);
    });
  }; 

return (

   <form
        onSubmit={handleSubmit}
        className="flex flex-col justify-start w-full mt-lg "
      >
        <div className="flex flex-row justify-between mx-auto max-w-screen-xs space-x-2">
          <input
            type="text"
            className="text-xl w-10 text-center bg-transparent  border-t-0 border-l-0 border-r-0 focus:ring-0 focus:border-gray-400 border-b border-gray-400 h-10 "
            pattern="[0-9]"
            maxLength={1}
            value={digitOne}
            onChange={(e) => setDigitOne(e.target.value)}
          />
          <input
            type="text"
            className="text-xl w-10 text-center bg-transparent  border-t-0 border-l-0 border-r-0 focus:ring-0 focus:border-gray-400 border-b border-gray-400 h-10 "
            pattern="[0-9]"
            maxLength={1}
            value={digitTwo}
            onChange={(e) => setDigitTwo(e.target.value)}
          />
          <input
            type="text"
            className="text-xl w-10 text-center bg-transparent  border-t-0 border-l-0 border-r-0 focus:ring-0 focus:border-gray-400 border-b border-gray-400 h-10 "
            pattern="[0-9]"
            maxLength={1}
            value={digitThree}
            onChange={(e) => setDigitThree(e.target.value)}
          />
          <input
            type="text"
            className="text-xl w-10 text-center bg-transparent  border-t-0 border-l-0 border-r-0 focus:ring-0 focus:border-gray-400 border-b border-gray-400 h-10 "
            pattern="[0-9]"
            maxLength={1}
            value={digitFour}
            onChange={(e) => setDigitFour(e.target.value)}
          />
          <input
            type="text"
            className="text-xl w-10 text-center bg-transparent  border-t-0 border-l-0 border-r-0 focus:ring-0 focus:border-gray-400 border-b border-gray-400 h-10 "
            pattern="[0-9]"
            maxLength={1}
            value={digitFive}
            onChange={(e) => setDigitFive(e.target.value)}
          />
        </div>
        <button className="uppercase flex-grow mt-6 p-2 bg-red-500 text-white px-4 rounded mx-lg">
          proceed
        </button>
      </form>

);

Actions

import ApiInstance from "../../Api/root";
import store from "../store";
import { CHECK_VERIFIED } from "../Types/CustomerVerificationTypes";
import {
  CUSTOMER_LOGIN_SUCCESS,
  GET_CUSTOMER_LOGIN,
} from "../Types/CustomerLoginTypes";

export const checkVerification =
  ({ user_info, otp }) =>
  async (dispatch, getState) => {
    const deviceId = getState().device.device.data.device.id;
    localStorage.setItem("id", deviceId);
    console.log(otp);
    const res = await ApiInstance.get(
      `customers/otp/verification?mobile_number=${user_info.mobile_number}&country_code=${user_info.country_code}&otp=${otp}&device_id=${deviceId}`,
      {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json",
        },
      }
    )
      .then((res) => {
        console.log("Auth Token", res.data);
        dispatch({
          type: CHECK_VERIFIED,
          payload: res.data,
        });

        // todo only if API Call is success
        if (res.data.success) {
          localStorage.setItem("authToken", res.data.token);
        } else {
          alert("Entered OTP is wrong, Try Again");
        }
      })
      .catch((error) => {
        console.error(error);
      });
  };

Also I've set maxLength of input to 1 but How do I move one input to another after user puts a number?

Chandler Bing
  • 410
  • 5
  • 25
  • Are you asking how to do this `const otp = { digitOne, digitTwo, digitThree, digitFour, digitFive };`? It's a little unclear what you are asking for, or if there's an issue. – Drew Reese Jul 16 '21 at 05:50
  • @DrewReese sorry about that. Yes I want to store those value in just one variable which is otp here. I can't do this with my approach because it return an object. – Chandler Bing Jul 16 '21 at 05:52
  • 1
    What returns an object? `otp`? Of course`otp` an object, that's how you pack variables into a single object. Are you needing to unpack the values in your async action or some reducer? – Drew Reese Jul 16 '21 at 05:54
  • Yes I want to unpack the values and pass it to my actions. In my API I want pure numbers – Chandler Bing Jul 16 '21 at 05:55
  • I see, can you update your question to include all the code you're trying to handle this `checkVerification` action? – Drew Reese Jul 16 '21 at 05:56
  • sure, give me sec. – Chandler Bing Jul 16 '21 at 05:56
  • BTW, to "unpack" the object properties, use destructuring assignment, i.e. `const { digitOne, digitTwo, digitThree, digitFour, digitFive } = otp`. – Drew Reese Jul 16 '21 at 06:01
  • right but it will just say assigned a value but never used – Chandler Bing Jul 16 '21 at 06:03
  • ***What*** will say assigned a value but never used? Please try to fully explain what it is that you are trying to do, and include any error/warning messages up front. – Drew Reese Jul 16 '21 at 06:05
  • If I use `const { digitOne, digitTwo, digitThree, digitFour, digitFive } = otp` It just says these five variables are assigned but never used. just a warning.Then if I submit the OTP it gives me an error of TypeError: Cannot destructure property 'digitOne' of 'otp' as it is null. – Chandler Bing Jul 16 '21 at 06:09
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/234953/discussion-between-drew-reese-and-random-18). – Drew Reese Jul 16 '21 at 06:12

1 Answers1

0

Add The Following Code To Move A The Curosor To Next Input After Adding A Input. Please Validate Cause it will take some time to reproduce and test the answer. anywas you can do this by using the .focus() function on the element.:

 const [otp, setOtp] = useState(null);
  const [digitOne, setDigitOne] = useState(null);
  const [digitTwo, setDigitTwo] = useState(null);
  const [digitThree, setDigitThree] = useState(null);
  const [digitFour, setDigitFour] = useState(null);
  const [digitFive, setDigitFive] = useState(null);

  const handleSubmit = (e) => {
    e.preventDefault();
    const otp = { digitOne, digitTwo, digitThree, digitFour, digitFive };
    console.log(digitOne, digitTwo, digitThree, digitFour, digitFive);
    dispatch(checkVerification({ user_info, otp })).then(() => {
      console.log(otp);
    });
  }; 

return (

   <form
        onSubmit={handleSubmit}
        className="flex flex-col justify-start w-full mt-lg "
      >
        <div className="flex flex-row justify-between mx-auto max-w-screen-xs space-x-2">
          <input
            type="text"
            className="text-xl w-10 text-center bg-transparent  border-t-0 border-l-0 border-r-0 focus:ring-0 focus:border-gray-400 border-b border-gray-400 h-10 "
            pattern="[0-9]"
            maxLength={1}
            value={digitOne}
            onChange={(e) => {
    setDigitOne(e.target.value)
    document.getElementById('digitTwo').focus()
            }}
            id="digOne"
          />
          <input
            type="text"
            className="text-xl w-10 text-center bg-transparent  border-t-0 border-l-0 border-r-0 focus:ring-0 focus:border-gray-400 border-b border-gray-400 h-10 "
            pattern="[0-9]"
            maxLength={1}
            value={digitTwo}
            id="digitTwo"
            onChange={(e) => {
    setDigitTwo(e.target.value)
    document.getElementById('digitThree').focus()
            }}

          />
          <input
            type="text"
            className="text-xl w-10 text-center bg-transparent  border-t-0 border-l-0 border-r-0 focus:ring-0 focus:border-gray-400 border-b border-gray-400 h-10 "
            pattern="[0-9]"
            maxLength={1}
            value={digitThree}
    id="digitThree"
            onChange={(e) => {
    setDigitThree(e.target.value)
    document.getElementById('digitFour').focus()
            }}
    enter code here
          />
          <input
            type="text"
            className="text-xl w-10 text-center bg-transparent  border-t-0 border-l-0 border-r-0 focus:ring-0 focus:border-gray-400 border-b border-gray-400 h-10 "
            pattern="[0-9]"
            maxLength={1}
            value={digitFour}
    id="digitFour"
           onChange={(e) => {
    setDigitFour(e.target.value)
    document.getElementById('digitFive').focus()
            }}
    enter code here
          />
          <input
            type="text"
            className="text-xl w-10 text-center bg-transparent  border-t-0 border-l-0 border-r-0 focus:ring-0 focus:border-gray-400 border-b border-gray-400 h-10 "
            pattern="[0-9]"
            maxLength={1}
            value={digitFive}
           id="digitFive"
            onChange={(e) => {
    setDigitFIve(e.target.value)
            }}
          />
        </div>
        <button className="uppercase flex-grow mt-6 p-2 bg-red-500 text-white px-4 rounded mx-lg">
          proceed
        </button>
      </form>

);

Please Mark It As Correct If It Works!

Kamestart

kamestart
  • 51
  • 1
  • 9