Float types with inputs?


I’m trying to make a simple money app with Elm 1.19.1. When a user enters a value in the input I’m setting that value on the model. I’m also re-painting the input with the value that was just entered. Meaning if the user provided something invalid then it will default to something other than what they entered.

This works great for integers. But for floats something like “32.” instantly breaks because the period is removed by the update function (String.toFloat |> Maybe.withDefault model.value). I’m wondering what is the best way to manage this?

type Model alias = { value : Float }

type Msg = SetValue String

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        SetValue val ->
            ( { model | value = val |> String.toFloat |> Maybe.withDefault model.value }, Cmd.none )

view : Model -> Html Msg
view model =
    input [ onInput SetValue, value model.value ] [ ]

I don’t want to store it as a string on the model because I feel like I lose that free validation. But I don’t know. Whats the best practice here?

1 Like

Generally, you will want to store the exact input in the model (as a string). When you want to display an error message (perhaps on field blur, or maybe only when submitting the form), you would run a validation function that returns Result Float ValidationError or a type like that.

I’ve used hecrj/composable-form in the past, which does a great job of abstracting a lot of this (although it might be a bit complex for a small project).

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.