Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to get the value of input tag onSubmit without using onChange in React js/Typescript?

I have no other special events onChange so I need to simplify my code by only handling events onSubmit specifically on the Form tag.

I’m creating a simple Form in Typescript in React and When I click Submit, I want to log the value of the input box in the console. But I get an error when I do this.

import React from "react";

const handleSubmit =(event:React.FormEvent<HTMLFormElement>) =>{
    event.preventDefault();
    console.log(event.currentTarget[0].value);
  };

export const InputForm: React.FC  = () =>{
    return (
        <form className='form-container' onSubmit={handleSubmit}>
            <input className="input" placeholder="Enter value" required />
            <button type="submit">Enter</button>
          </form>  
      )
}

My reasoning for this line => console.log(event.currentTarget[0].value); is that the form tag has 2 elements, input and button, so event.currentTarget[0] alone returns the input tag in the console but it passes an error(Property ‘value’ does not exist on type ‘Element’.ts(2339)) when i try to add .value

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The problem is that event.currentTarget[0] is just of type Element, and Element doesn’t have value (which is just on certain elements, like HTMLInputElement, HTMLSelectElement, etc.).

You know it’s an Element subtype with value, but TypeScript doesn’t, because not all form control elements have value (fieldset and object don’t, for a start, but they’re counted as form elements).

You can put a utility assertion function in your toolkit:

function assertIsFormFieldElement(element: Element): asserts element is HTMLInputElement | HTMLSelectElement | HTMLButtonElement {
// Customize this list as necessary −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    if (!("value" in element)) {
        throw new Error(`Element is not a form field element`);
    }
}

…then use it:

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) =>{
    event.preventDefault();
    const firstField = event.currentTarget[0];
    assertIsFormFieldElement(firstField);
    console.log(firstField.value);
};

Playground link


Side note: If you’re going to do this, you might consider putting a name on the input and using that when looking up the element, rather than assuming the input will be the first element:

<input name="the-name" className="input" placeholder="Enter value" required />

Then you can use a utility function to get the named item from the form:

function getFormControl(form: HTMLFormElement, name: string): HTMLInputElement | HTMLSelectElement | HTMLButtonElement /* | ...*/ {
    const control = form.elements.namedItem(name);
    if (!control || control instanceof RadioNodeList || !("value" in control)) {
        throw new Error(`Form control "${name}" not found or was a RadioNodeList`);
    }
    return control;
} 

// ...


const handleSubmit = (event: React.FormEvent<HTMLFormElement>) =>{
    event.preventDefault();
    const inputField = getFormControl(event.currentTarget, "the-name");
    console.log(inputField.value);
};

Playground link

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading