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

Unable to use functions with multiple arguments #27

Closed
cmeeren opened this issue Aug 24, 2019 · 7 comments
Closed

Unable to use functions with multiple arguments #27

cmeeren opened this issue Aug 24, 2019 · 7 comments

Comments

@cmeeren
Copy link
Contributor

cmeeren commented Aug 24, 2019

Material-UI contains many onChange props where the handler accepts two arguments. However, these functions are never invoked.

For example, a prop definition may look like this:

static member inline onChange(handler: Event -> bool -> unit) = Interop.mkAttr "onChange" handler

If I remove bool from the signature, it works, but of course then the handler doesn't get access to that value.

This behaviour seems consistent across all multi-argument functions I've tried. And it works fine when using Fable.MaterialUI, which has a DU prop | OnChange of (obj->bool->unit).

I'm a bit stuck debugging this. Do you have any idea why this could be?

@cmeeren cmeeren mentioned this issue Aug 24, 2019
@Zaid-Ajaj
Copy link
Owner

Zaid-Ajaj commented Aug 24, 2019

It most likely has to do with currying the handler function, can you try this:

static member inline onChange(handler: Event -> bool -> unit) = 
    Interop.mkAttr "onChange" (fun (ev, capture) -> handler ev capture) 

or if you tolerate tuples in the handler definition

static member inline onChange(handler: (Event * bool) -> unit) = 
    Interop.mkAttr "onChange" handler

@cmeeren
Copy link
Contributor Author

cmeeren commented Aug 24, 2019

Thanks! I tried both, and now the handler is called, but both params are undefined, so I'm still lost. (They work fine if I remove the second parameter from the signature.)

@Zaid-Ajaj
Copy link
Owner

Hmm that's weird, can you try using System.Func?

static member inline onChange(handler: System.Func<Event, bool, unit>) = 
    Interop.mkAttr "onChange" handler

@cmeeren
Copy link
Contributor Author

cmeeren commented Aug 24, 2019

Yep, that works fine. But of course makes the signature more noisy.

Any idea what's going on?

Edit: This also works, so at least there's a user-invisible workaround:

static member inline onChange(handler: Event -> ReactElement -> unit) =
  Interop.mkAttr "onChange" (System.Func<_,_,_> handler)

@Zaid-Ajaj
Copy link
Owner

Any idea what's going on?

This is just how Fable compiles functions, using System.Func tells Fable that we want the functions compiled the JS way (i.e. uncurried)

@cmeeren
Copy link
Contributor Author

cmeeren commented Aug 26, 2019

I see. So using Func is the only way to make this work, or are there other syntaxes, too?

@Zaid-Ajaj
Copy link
Owner

I think Func is the way to go, you could probably do some weird uncurrying with [<Emit(...)>] but it could be tricky (I haven't tried it)

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

No branches or pull requests

2 participants