I am struggling to decode a Json string.
I receive the following json
from a server:
“[{"A":1,"B":6},{"A":2,"B":7},{"A":3,"B":8},{"A":4,"B":9},{"A":5,"B":10}]”
I have writen the following code to decode the json into my own types:
import Json.Decode as Decode exposing (Decoder, decodeString, float, int, list, string)
type alias RowRecord =
{ a : Int
, b : Int
}
type alias DF =
List RowRecord
rowDecoder : Decoder RowRecord
rowDecoder =
Decode.map2 RowRecord
(Decode.field "A" int)
(Decode.field "B" int)
dfDecoder : Decoder DF
dfDecoder =
Decode.list rowDecoder
My code compiles when using elm repl
:
> jsonString = "[{\"A\":1,\"B\":6},{\"A\":2,\"B\":7},{\"A\":3,\"B\":8},{\"A\":4,\"B\":9},{\"A\":5,\"B\":10}]"
> Decode.decodeString dfDecoder jsonString
Ok [{ a = 1, b = 6 },{ a = 2, b = 7 },{ a = 3, b = 8 },{ a = 4, b = 9 },{ a = 5, b = 10 }]
: Result Decode.Error DF
However, my attempt to decode the json
file when coming from a server is failing. The code is compiling but I reveive a message saying
“BadBody "Problem with the given value:\n\n\"\\\"[{\\\\\\\"A\\\\\\\":1,\\\\\\\"B\\\\\\\":6},{\\\\\\\"A\\\\\\\":2,\\\\\\\"B\\\\\\\":7},{\\\\\\\"A\\\\\\\":3,\\\\\\\"B\\\\\\\":8},{\\\\\\\"A\\\\\\\":4,\\\\\\\"B\\\\\\\":9},{\\\\\\\"A\\\\\\\":5,\\\\\\\"B\\\\\\\":10}]\\\"\"\n\nExpecting a LIST"” }
module Main exposing (main)
import Browser
import Html exposing (Html, div, input, label, text)
import Html.Events exposing (onInput)
import Http
import Json.Decode as Decode exposing (Decoder, int)
-- Define types and decoders
type alias RowRecord =
{ a : Int
, b : Int
}
rowDecoder : Decoder RowRecord
rowDecoder =
Decode.map2 RowRecord
(Decode.field "A" int)
(Decode.field "B" int)
type alias DF =
List RowRecord
dfDecoder : Decoder DF
dfDecoder =
Decode.list rowDecoder
getDataFrame : Cmd Msg
getDataFrame =
Http.get
{ url = "http://localhost:5051/df"
, expect = Http.expectJson DFReceived dfDecoder
}
-- define Model
type alias Model =
{ df : DF, error : String }
initialModel : Model
initialModel =
{ df = [ RowRecord 0 0 ], error = "" }
-- define Msg
type Msg
= InputChanged String
| DFReceived (Result Http.Error DF)
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
InputChanged newInput ->
( model, getDataFrame )
DFReceived result ->
case result of
Ok newDF ->
( { model | df = newDF }, Cmd.none )
Err error ->
( { model | error = Debug.toString error }, Cmd.none )
view : Model -> Html Msg
view model =
div []
[ label [] [ text "Label" ]
, input [ onInput InputChanged ] []
, text (Debug.toString model)
]
main : Program () Model Msg
main =
Browser.element
{ init = \flags -> ( initialModel, Cmd.none )
, view = view
, update = update
, subscriptions = \_ -> Sub.none
}
I would be greatful for any hint!
Sorry for asking these basic questions but it is really hard to find answers anywhere. This is clearly a downside of Elm. On the upside the Elm community is really helpful (also with complete newbies). Thanks for this!