Decoder a -> a?

In decoders there is a pattern that looks like this:
(field "id" int)
I want to see the resulting value of this immediately because there is another field that I want to set based on the id. How can I do that?

participantDecoder : Int -> Decoder Participant
participantDecoder id =
    let
        actualInt =
            field "id" int -- need to turn into actual int

        idsMatch =
            id == actualInt -- Int /= Decoder Int
    in
    D.map2 Participant
        (field "id" int)
        (D.succeed idsMatch)

Edit: See Atlewee’s post for an andThen example.

map can do this, but in many complex cases andThen will be more useful.

participantDecoder : Int -> Decoder Participant
participantDecoder id =
    let
        fromId : Int ->  Participant
        fromId decodedId =
            (Participant decodedId (decodedId == id))
    in
    field "id" int
        |> D.map fromId
3 Likes

indeed my favourite debug trick, appending a

|> map (Debug.log "here")
3 Likes

You can use something like this : :slight_smile:

decodeMsg jsValue =
    D.field "id" D.string
        |> D.andThen decodePayload

decodePayload id=
    case id of
        "IntPayload" ->
            ... the entire msg to be decoded here, and id is already deoded and available...

        "StringPayload" ->
            D.field "payload" (D.map ItHasStringPayload D.string)

        _ ->
            D.fail <| "Event with unknown id: " ++ id

Edit: I guess for your usecase:

decodeMsg jsValue =
    D.field "id" D.int
        |> D.andThen (\idAsInt ->
            ... your decoder... (id is available as Int here) 
            )

But I would not have any logic in my decoders,
I would have just decoded it as is and then check if the Id match in my update function.

1 Like

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