Sök…


Anmärkningar

Json.Decode exponerar två funktioner för att avkoda en nyttolast, den första är decodeValue som försöker avkoda en Json.Encode.Value , den andra är decodeString som försöker avkoda en JSON-sträng. Båda funktionerna tar två parametrar, en avkodare och en Json.Encode.Value eller Json-sträng.

Avkoda en lista

Följande exempel kan testas på https://ellie-app.com/m9tk39VpQg/0 .

import Html exposing (..)
import Json.Decode 

payload =
  """
  ["fu", "bar"]
  """

main =
  Json.Decode.decodeString decoder payload -- Ok ["fu","bar"]
  |> toString
  |> text

decoder =
  Json.Decode.list Json.Decode.string

Föravkoda ett fält och avkoda resten beroende på det avkodade värdet

Följande exempel kan testas på https://ellie-app.com/m9vmQ8NcMc/0 .

import Html exposing (..)
import Json.Decode

payload =
  """
  [ { "bark": true, "tag": "dog", "name": "Zap", "playful": true }
  , { "whiskers": true, "tag" : "cat", "name": "Felix" }
  , {"color": "red", "tag": "tomato"}
  ]
  """

-- OUR MODELS

type alias Dog =
  { bark: Bool
  , name: String
  , playful: Bool
  }
  
type alias Cat =
  { whiskers: Bool
  , name: String
  }

-- OUR DIFFERENT ANIMALS

type Animal 
  = DogAnimal Dog
  | CatAnimal Cat
  | NoAnimal

main =
  Json.Decode.decodeString decoder payload
  |> toString
  |> text

decoder =
  Json.Decode.field "tag" Json.Decode.string
    |> Json.Decode.andThen animalType
    |> Json.Decode.list 

animalType tag =
  case tag of
    "dog" ->
      Json.Decode.map3 Dog 
          (Json.Decode.field "bark" Json.Decode.bool) 
          (Json.Decode.field "name" Json.Decode.string) 
          (Json.Decode.field "playful" Json.Decode.bool) 
        |> Json.Decode.map DogAnimal
    "cat" ->
      Json.Decode.map2 Cat 
          (Json.Decode.field "whiskers" Json.Decode.bool) 
          (Json.Decode.field "name" Json.Decode.string)
        |> Json.Decode.map CatAnimal
    _ ->
      Json.Decode.succeed NoAnimal

Avkodning av JSON från Rust enum

Detta är användbart om du använder rost i backend och alm i främre änden

enum Complex{
    Message(String),
    Size(u64)
}

let c1 = Complex::Message("hi");
let c2 = Complex::Size(1024u64);

Den kodade Json från rost kommer att vara:

c1:
    {"variant": "Message",
     "fields": ["hi"]
    }
c2:
    {"variant": "Size",
     "fields": [1024]
    }

Avkodaren i alm

import Json.Decode as Decode exposing (Decoder)

type Complex = Message String
    | Size Int

-- decodes json to Complex type
complexDecoder: Decoder Value
complexDecoder = 
    ("variant" := Decode.string `Decode.andThen` variantDecoder)

variantDecoder: String -> Decoder Value
variantDecoder variant =
    case variant of
        "Message" ->
            Decode.map Message 
                ("fields" := Decode.tuple1 (\a -> a) Decode.string)
        "Size" ->
            Decode.map Size
                ("fields" := Decode.tuple1 (\a -> a) Decode.int)
        _ ->
            Debug.crash "This can't happen"

Användning: data begärs från http rest api och avkodningen av nyttolasten kommer att ske

    Http.fromJson complexDecoder payload

Avkodning från sträng kommer att vara

    Decode.decodeString complexDecoder payload

Avkoda en lista med poster

Följande kod kan hittas i en demo här: https://ellie-app.com/mbFwJT9jD3/0

import Html exposing (..)
import Json.Decode exposing (Decoder)

payload =
  """
  [{
      "id": 0,
      "name": "Adam Carter",
      "work": "Unilogic",
      "email": "[email protected]",
      "dob": "24/11/1978",
      "address": "83 Warner Street",
      "city": "Boston",
      "optedin": true
    },
    {
      "id": 1,
      "name": "Leanne Brier",
      "work": "Connic",
      "email": "[email protected]",
      "dob": "13/05/1987",
      "address": "9 Coleman Avenue",
      "city": "Toronto",
      "optedin": false
    }]
  """
  
type alias User =
  { name: String
  , work: String
  , email: String
  , dob: String
  , address: String
  , city: String
  , optedin: Bool
  }
 
main =
  Json.Decode.decodeString decoder payload
  |> toString
  |> text

decoder: Decoder (List User)
decoder =
    Json.Decode.map7 User 
    (Json.Decode.field "name" Json.Decode.string)
    (Json.Decode.field "work" Json.Decode.string)
    (Json.Decode.field "email" Json.Decode.string)
    (Json.Decode.field "dob" Json.Decode.string)
    (Json.Decode.field "address" Json.Decode.string)
    (Json.Decode.field "city" Json.Decode.string)
    (Json.Decode.field "optedin" Json.Decode.bool)
    |> Json.Decode.list 

Avkoda ett datum

Om du har json med en ISO-datumsträng som denna

JSON.stringify({date: new Date()})
// -> "{"date":"2016-12-12T13:24:34.470Z"}"

Du kan kartlägga den till elm Date :

import Html exposing (text)
import Json.Decode as JD
import Date

payload = """{"date":"2016-12-12T13:24:34.470Z"}"""

dateDecoder : JD.Decoder Date.Date
dateDecoder =
  JD.string
    |> JD.andThen ( \str ->
          case Date.fromString str of
            Err err -> JD.fail err
            Ok date -> JD.succeed date )

payloadDecoder : JD.Decoder Date.Date
payloadDecoder =
  JD.field "date" dateDecoder

main =
  JD.decodeString payloadDecoder payload
  |> toString
  |> text

Avkoda en lista med objekt som innehåller listor med objekt

Se Ellie för ett fungerande exempel. Detta exempel använder NoRedInk / elm-decode-pipeline- modulen.

Får en lista med JSON-objekt, som själva innehåller listor med JSON-objekt:

[
  {
    "id": 0,
    "name": "Item 1",
    "transactions": [
      { "id": 0, "amount": 75.00 },
      { "id": 1, "amount": 25.00 }
    ]
  },
  {
    "id": 1,
    "name": "Item 2",
    "transactions": [
      { "id": 0, "amount": 50.00 },
      { "id": 1, "amount": 15.00 }
    ]
  }
]

Om strängen ovan finns i payload kan den avkodas med följande:

module Main exposing (main)

import Html exposing (..)
import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Pipeline as JP
import String


type alias Item =
    { id : Int
    , name : String
    , transactions : List Transaction
    }


type alias Transaction =
    { id : Int
    , amount : Float
    }


main =
    Decode.decodeString (Decode.list itemDecoder) payload
        |> toString
        |> String.append "JSON "
        |> text



itemDecoder : Decoder Item
itemDecoder =
    JP.decode Item
        |> JP.required "id" Decode.int
        |> JP.required "name" Decode.string
        |> JP.required "transactions" (Decode.list transactionDecoder)


transactionDecoder : Decoder Transaction
transactionDecoder =
    JP.decode Transaction
        |> JP.required "id" Decode.int
        |> JP.required "amount" Decode.float


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow