This is idential to this question, except elm has changed since then so that answer is no longer valid (in particular there is no longer a Decode.customDecoder
object).
How do you do this same thing in elm-core > 5.0.0?
You can create your own custom decoder by using succeed
and fail
from Json.Decode
. I changed the argument order below to make it chainable.
Edit: separated decoder concerns from result concerns.
import Json.Decode as Json
import Result
-- // This is a Result helper function that could be used elsewhere.
-- // Currently, there is no Result.either in Elm core.
eitherR : (x -> b) -> (a -> b) -> Result x a -> b
eitherR fErr fOk result =
case result of
Err x ->
fErr x
Ok a ->
fOk a
customDecoder : (a -> Result String b) -> Json.Decoder a -> Json.Decoder b
customDecoder fResult decoder =
decoder |> Json.andThen (fResult >> eitherR Json.fail Json.succeed)
Plugging this in to the linked question...
let number =
Json.oneOf [ Json.int, Json.string |> customDecoder String.toInt ]
Here's another example use. This is a version of onChange
which converts the value to an integer. Mainly useful for select
when you know the option value is an Int.
import Html
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import String
onChangeInt : (Int -> msg) -> Attribute msg
onChangeInt fMsg =
on "change" (targetValue |> customDecoder String.toInt |> Json.map fMsg)
Note that targetValue
is defined in the Html.Events module:
targetValue : Decoder String