Buscar..


Observaciones

Json.Decode expone dos funciones para decodificar una carga útil, la primera es decodeValue que intenta descodificar un Json.Encode.Value , la segunda es decodeString que intenta descodificar una cadena JSON. Ambas funciones toman 2 parámetros, un decodificador y una cadena Json.Encode.Value o Json.

Decodificando una lista

El siguiente ejemplo se puede probar en 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

Pre-decodifique un campo y decodifique el resto dependiendo de ese valor decodificado

Los siguientes ejemplos se pueden probar en 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

Decodificación JSON de Rust enum

Esto es útil si usa óxido en la parte posterior y olmo en la parte delantera

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

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

El Json codificado de la herrumbre será:

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

El decodificador en olmo.

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"

Uso: los datos se solicitan desde http api api y la decodificación de la carga útil será

    Http.fromJson complexDecoder payload

La decodificación de la cadena será

    Decode.decodeString complexDecoder payload

Decodificando una lista de registros

El siguiente código se puede encontrar en una demostración aquí: 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 

Decodificar una fecha

En caso de que tenga json con una cadena de fecha ISO como esta

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

Puedes mapearlo en elm Tipo de 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

Decodificar una lista de objetos que contienen listas de objetos

Ver Ellie para un ejemplo de trabajo. Este ejemplo utiliza el módulo NoRedInk / elm-decode-pipeline .

Dada una lista de objetos JSON, que a su vez contienen listas de objetos JSON:

[
  {
    "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 }
    ]
  }
]

Si la cadena anterior está en la cadena de payload , puede decodificarse utilizando lo siguiente:

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow