Elm Language
Json.Decodificar
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