Type safety and drop-down lists

Hi,

I want to write a tiny app to teach children about binary data. One of the things I want to discuss, is that it doesn’t matter if I talk about 0/1, High/Low-values or any other possible represantion of binary data. Therefore the binary data should be displayed in different ways which can be selected via a drop-down list. You can find a simplified version of it here:

https://ellie-app.com/vDY3pyWgB5ga1

(In the real app the binary data can be changed)

Everything works as intended, but I don’t like that the information how the binary data should be displayed is stored as a String. Instead I would like to use a more specific type.

You can find a variant (that doesn’t work) here:

https://ellie-app.com/vDXTMcBPFjwa1

I guess what I would need is something like

onInput : (a -> msg) -> Attribute msg

instead of

onInput : (String -> msg) -> Attribute msg

and

value : a -> Attribute msg

instead of

value : String -> Attribute msg

Do you have any ideas how the view function can be implemented without converting every ViewType to/from String?

Kinds regards, Tom

I think this should work, though I’ve only tested in Firefox https://ellie-app.com/vDZDKvD6wd9a1

1 Like

@wolfadex your version seems to only work in Firefox, and even in Firefox it’s not ideal: It does not work if you control the select with the keyboard.

Here’s how I do it: https://ellie-app.com/vF49jYFQYRDa1

You can even generalize it into a select helper function so you don’t need to do all the dance with the decoder every time.

2 Likes

I’ve found this library to have a pretty good API for this sort of thing:

https://elm.dmy.fr/packages/Confidenceman02/elm-select/latest/

1 Like

Thank you, that’s great!

I am trying to better understand Decoders and made a tiny example that has Int as Model and Msg:
https://ellie-app.com/vFjLwfx9z8ja1

That works. After writing this, I thought that it doesn’t make sense to write this decoder, because there is a built-in decoder for Int. So I changed my program to use Decode.int instead of the custom decoder:
https://ellie-app.com/vFjMYWwfWpLa1

It still compiles, but doesn’t do anything when changing the number. It seems to me that the decoder always fails and no message is sent, because I can’t see any message in the debug window.

Is that right and why doesn’t it work?

That is right! You have just discovered the downside in Elm’s design of using “decoder failure” to mean “ignore event” – you don’t get any feedback about what’s wrong when there’s a problem with your decoder!

Luckily, there’s a way to see the actual error: Debugging DOM event handlers in Elm

I copied loggingDecoder from that article into your example: https://ellie-app.com/vFmwvcyRfFJa1

When you type into the input field, you’ll see this in the browser console:

Problem with the given value:

{
        "isTrusted": true
    }

Expecting an INT

The thing that you get to decode when using the on function is an object, but you were expecting an integer (since you supplied Decode.int as the decoder).

In reality, the object has more stuff than just isTrusted in it, but it looks like that in the error message because of JavaScript reasons. Here’s the documentation for the actual object: Event - Web APIs | MDN. (That’s the base class, there are more specific event classes that extend it.)

In your first Ellie, you used targetValue, which is implemented like this:

targetValue : Json.Decoder String
targetValue =
  Json.at ["target", "value"] Json.string

There you can see how the decoder goes into target property, which in your case is an HTMLInputElement, which has a value property.

value is always a string! So Decode.int wouldn’t work there. You have to use Decode.string and then try to parse it into an int.

If you use <input type="number">, you can read valueAsNumber instead, which can be an int sometimes, but has its own quirks.

2 Likes

Thank you for the great help!

I love how nice and simple Elm is … as long as you have not to deal with the outside world.