module Example exposing (main) import Browser import Html exposing (..) import Html.Attributes import Html.Events import Json.Decode ---- MODEL ---- type Model = Spa1 State1 | Spa2 State2 | Error String type alias State1 = { one : String } type alias State2 = { one : String, two : Int } decode : String -> Model decode str = case Json.Decode.decodeString modelDecoder str of Ok (Spa1 data) -> let _ = Debug.log "result" data in Spa1 data Ok (Spa2 data) -> Spa2 data Ok (Error err) -> Error err Err err -> let _ = Debug.log "Could not decode" err in Error <| Json.Decode.errorToString err modelDecoder : Json.Decode.Decoder Model modelDecoder = Json.Decode.oneOf [ Json.Decode.map Spa2 state2Decoder , Json.Decode.map Spa1 state1Decoder ] state1Decoder : Json.Decode.Decoder State1 state1Decoder = Json.Decode.map State1 (Json.Decode.field "one" Json.Decode.string) state2Decoder : Json.Decode.Decoder State2 state2Decoder = Json.Decode.map2 State2 (Json.Decode.field "one" Json.Decode.string) (Json.Decode.field "two" Json.Decode.int) ---- PROGRAM ---- main : Program () Model Msg main = Browser.sandbox { init = Error "No data parsed yet" , view = view , update = update } ---- VIEW ---- view : Model -> Html Msg view model = div [ Html.Attributes.style "margin" "1em" ] [ h1 [] [ text "Model from multiple decoders" ] , render model , textarea [ Html.Events.onInput Parse --, Html.Attributes.autofocus True , Html.Attributes.placeholder "Enter JSON formatted data" , Html.Attributes.style "min-height" "7em" , Html.Attributes.style "min-width" "80%" ] [] , br [] [] , h3 [] [ text "Supported json structures:" ] , ul [] [ li [] [ text "{ \"one\": \"String\" }" ] , li [] [ text "{ \"one\": \"String\", \"two\" : 3 }" ] ] ] render : Model -> Html msg render model = case model of Error str -> String.split "\n" str |> List.filter (not << String.isEmpty) |> List.map (\s -> p [] [ text s ]) |> div [] _ -> p [] [ text <| Debug.toString model ] ---- UPDATE ---- type Msg = Parse String update : Msg -> Model -> Model update msg model = case msg of Parse str -> decode str