Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

property value not found in EventTarget #2099

Closed
cristiancedenogallego opened this issue Jul 19, 2016 · 22 comments
Closed

property value not found in EventTarget #2099

cristiancedenogallego opened this issue Jul 19, 2016 · 22 comments

Comments

@cristiancedenogallego
Copy link

error: SyntheticKeyboardEvent property value: Property not found in EventTarget

Example:

const proxyKeyUp = ({ key, target, preventDefault }: SyntheticKeyboardEvent) => {
    if (!/([0-9]|\.|,)/.test(key)) {
      return preventDefault();
    }

    console.log(target.value);
    const inputKey = key === ',' ? '.' : key;

    return onKeyUp(`${inputRef.value}${inputKey}`);
  };
@avikchaudhuri
Copy link
Contributor

avikchaudhuri commented Jul 19, 2016

I don't see value declared in EventTarget. https://github.com/facebook/flow/blob/master/lib/dom.js#L98

Any chance you can point to a spec that says value should be a property of EventTargets?

@cristiancedenogallego
Copy link
Author

cristiancedenogallego commented Jul 20, 2016

not appear in spec
https://dom.spec.whatwg.org/#interface-eventtarget

but if i run the code target.value return a value, please see
http://www.w3schools.com/jsref/event_target.asp

please see controlled components example
https://facebook.github.io/react/docs/forms.html#controlled-components

@cristiancedenogallego
Copy link
Author

cristiancedenogallego commented Jul 21, 2016

More info:

If i do

handleClick = ({ target }: { target: EventTarget }) => {
    if (!this.containerRef.contains(target)) {
      this.props.onClickOut();
    }
 };

EventTarget This type is incompatible with Node

@cristiancedenogallego
Copy link
Author

I decide to close this issue because not is recommended event.target, instead use refs for this

@ghost
Copy link

ghost commented Sep 22, 2016

@crisys11 can you elaborate and give an example?

@cristiancedenogallego
Copy link
Author

cristiancedenogallego commented Sep 22, 2016

in React

class Example extends Component {
   myref: HTMLElement;

   handler: void = () => {
     if (!this.containerRef.contains(this.myref)) {
       console.log('')
     }
   }

   render() {
     return <div onClick={this.handler} ref={r => {this.myref = r}}>some</div>
   }
}

or you can use 'this' for non react apps

 document.getElementById('a').addEventListener('click', function() {
  console.log(this);
 })

@vicapow
Copy link
Contributor

vicapow commented Oct 8, 2016

For others that may be confused by this as I was after recently upgrading flow (for me, to 0.33). EventTarget in the spec is an interface and could have more fields, like value. How could that happen? When EventTarget is also an Element, a Document, or the Window.

see: https://developer.mozilla.org/en/docs/Web/API/EventTarget

You can fix these errors by checking if target is an instance of window.HTMLInputElement.

Here's a quick example:

  _onModeChange(event: SyntheticEvent) {
    const {target} = event;
    if (!(target instanceof window.HTMLInputElement)) {
      return;
    }
    const newMode = APP_MODES.find(({name}) => {
      return name === target.value; // flow now knows `target` is an HTMLInputElement.
    });
    // [...]
  }

@alex-wilmer
Copy link

alex-wilmer commented Oct 11, 2016

😦 that workaround works but makes the code very odd to read

for the sake of this discussion, I'm not using React. I have just a normal div clickhandler that gets the id of the checkbox that was clicked

event.target.id

and get:

property id not found in EventTarget

@vicapow
Copy link
Contributor

vicapow commented Oct 12, 2016

To be clear, my comment isn't a workaround. This is a feature of Flowtype. Without flow, if you accidentally added this function as a listener to some object that didn't have a target value on its event, it would throw a runtime error.

@Dema
Copy link

Dema commented Jan 13, 2017

If you really don't want to test if the target is HTMLInputElement you can use typecast

 (event.target: window.HTMLInputElement).value

@gaearon
Copy link
Contributor

gaearon commented Mar 10, 2017

For what it's worth, instanceof check is a bit dangerous here because it doesn't work across iframes. So you may be breaking your code by trying to satisfy Flow in this case. I don't really know of a better solution though 😞

@jeffgran
Copy link

The React + Flow docs have this example for this case, which uses an intersection type:

onButtonEvent(event: Event & { currentTarget: HTMLButtonElement }) {
    // ...
  }

You could use HTMLInputElement, etc instead of HTMLButtonElement for other event types. Seems like the cleanest solution to me.

https://flow.org/en/docs/frameworks/react/

@deju
Copy link

deju commented Apr 26, 2017

@jeffgran Yes, it works for me.

onChange( event: Event & { target: HTMLInputElement } ) {
    // ...
}

@rvetere
Copy link

rvetere commented Apr 28, 2017

yes ... one of those things i totally hate about using Flow - such a piece of code looks SO much prettier to read if we just can leave out typing at all... all those instanceof checks and additional puttings into const of explicit types just to fullfill the sanity for flow is really a big pain.

Especially if you need 5min to implement the feature and then hacking around for hours just to get flow errors to 0 again.

The attitude "you should use refs so this is anyway the wrong way" is also not valid - as there are plenty of cases in real-world applications where a full ref-handling is just "another overkill" where the real solution could be so small/handy (and sexy without typing..)

@dinomite
Copy link

dinomite commented Jun 13, 2017

I made a type for my event in my types.js, which is listed as a [lib] in my .flowconfig:

declare type InputEvent = Event & {currentTarget: HTMLInputElement};

Then at the use site:

_handleFieldChange(field: string, event: InputEvent) {
    let new_state = {};
    new_state[field] = event.currentTarget.value;
    this.setState(new_state);
}

@kellyrmilligan
Copy link

i'm using flow 0.54.1, and this workaround isn't cutting it all of a sudden, any ideas?

@kellyrmilligan
Copy link

ok, the latest docs have it covered for anyone else:
https://flow.org/en/docs/react/events/

I used SyntheticEvent, and currentTarget for event.

@Pfuster12
Copy link

Just typing handleChange(event: SyntheticEvent<T>), where T is your element such as HTMLInputElement works on my end. Clean and simple. As @kellyrmilligan links, the latest docs should close this issue. 👍

@vkosovskikh
Copy link

Just approving above answers about using currentTarget. Possibly right solution:

onChange = (e: SyntheticInputEvent<HTMLInputElement>): void => {
    this.setState({ value: e.currentTarget.value });
}

@AhmedBHameed
Copy link

AhmedBHameed commented Oct 17, 2019

As i'm using react hooks with material ui which encountered into <InputBase> component,

<InputBase
             .....
              onChange={(e: SyntheticEvent) => onSearch(e)} // onSearch Sent as a prop
              .....           
/>

this solution bellow dose not work

onChange = (e: SyntheticInputEvent<HTMLInputElement>): void => {
    this.setState({ value: e.currentTarget.value });
}

But this way worked for me. TBH i'm not convinced with this approach but at least prevent types errors.

const onSearch = useCallback((e: SyntheticEvent) => {
    console.log((e.target as HTMLInputElement).value);
  }, []);

@cyan33
Copy link

cyan33 commented Dec 12, 2019

Using event.currentTarget instead of event.target will solve the issue.

@jonauz
Copy link

jonauz commented Mar 25, 2020

I ended up using such approach:

const onChange = (event: React.FormEvent<HTMLInputElement>) =>
    console.log(event.currentTarget.value);
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests