Ignore invalid item when decoding list

Generally the way you can deal with these is by decoding it to an Elm type that expresses the options, and then post processing with a map.

So for instance in your example, I would go for something like this:

decodeMaybeType : Decoder (Maybe Type)
decodeMaybeType =
    Decode.string
        |> Decode.map getTypeFromString 


decodeMaybeSection : Decoder (Maybe Section)
decodeMaybeSection =
    Decode.map2 (\maybeType index -> Maybe.map (\t -> Section t index) maybeType)
        (Decode.field "type" decodeMaybeType)
        (Decode.field "index" Decode.int)


decodeSections : Decoder (List Section)
decodeSections =
    Decode.list decodeMaybeSection
       |> Decode.map (List.filterMap identity)

NB: List.filterMap identity is a List (Maybe a) -> List a, it filters out the Nothing and gets rid of the Maybes in one go.


Given the comment by Quan Vo about one of many fields could be invalid, using Decode.oneOf might be a better fit.

You write the decoders for each field. If any field is illegal, the Section decoder fails and in oneOf, Nothing is returned.

(Here I am also using Json.Decode.Pipeline from NoRedInk).

import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (required)


type Type
    = A
    | B


type alias Section =
    { sectionType : Type
    , index : Int
    }


getTypeFromString : String -> Maybe Type
getTypeFromString input =
    case input |> String.toLower of
        "a" ->
            Just A

        "b" ->
            Just B

        _ ->
            Nothing


decodeType : Decoder Type
decodeType =
    Decode.string
        |> Decode.andThen
            (\str ->
                case getTypeFromString str of
                    Just sectionType ->
                        Decode.succeed sectionType

                    Nothing ->
                        Decode.fail <| ("Unknown type" ++ str)
            )


decodeSection : Decoder Section
decodeSection =
    Decode.succeed Section
        |> required "type" decodeType
        |> required "index" Decode.int

-- Either we succeed in decoding a Section or fail on some field.
decodeMaybeSection : Decoder (Maybe Section)
decodeMaybeSection =
    Decode.oneOf
        [ decodeSection |> Decode.map Just
        , Decode.succeed Nothing
        ]


decodeSections : Decoder (List Section)
decodeSections =
    Decode.list decodeMaybeSection
        |> Decode.map (List.filterMap identity)