基于字段值的条件JSON解码
Conditional JSON decoding based on a field value
我需要将 JSON 解码为如下所示的榆树类型:
类型
type User = Anonymous | LoggedIn String
type alias Model =
{ email_id : User
, id : Id
, status : Int
, message : String
, accessToken : AccessToken
}
JSON 消息 1
{
"status": 0,
"message": "Error message explaining what happened in server"
}
输入值
Model {
"email_id": Anonymous
, id: 0
, status: 0
, message: json.message
, accessToken: ""
}
JSON 消息 2
{
"status": 1,
"email_id": "asdfa@asdfa.com"
"token": "asdfaz.adfasggwegwegwe.g4514514ferf"
"id": 234
}
输入值
Model {
"email_id": LoggedIn json.email_id
, id: json.id
, status: json.status
, message: ""
, accessToken: json.token
}
解码器信息
以上,"message"并不总是存在,email_id/id/token总是不存在。
如何在 elm 中进行这种类型的条件解码
Json.Decode.andThen
允许您根据字段的值进行条件解析。在这种情况下,看起来你首先要提取 "status" 字段的值, andThen
根据它是 1
还是 [=14= 分别处理它].
编辑 2016-12-15:更新到 elm-0.18
import Html as H
import Json.Decode exposing (..)
type User = Anonymous | LoggedIn String
type alias Id = Int
type alias AccessToken = String
type alias Model =
{ email_id : User
, id : Id
, status : Int
, message : String
, accessToken : AccessToken
}
modelDecoder : Decoder Model
modelDecoder =
(field "status" int) |> andThen modelDecoderByStatus
modelDecoderByStatus : Int -> Decoder Model
modelDecoderByStatus status =
case status of
0 ->
map5
Model
(succeed Anonymous)
(succeed 0)
(succeed status)
(field "message" string)
(succeed "")
1 ->
map5
Model
(map LoggedIn (field "email_id" string))
(field "id" int)
(succeed status)
(succeed "")
(field "token" string)
_ ->
fail <| "Unknown status: " ++ (toString status)
main = H.div []
[ H.div [] [ decodeString modelDecoder msg1 |> Result.toMaybe |> Maybe.withDefault emptyModel |> toString |> H.text ]
, H.div [] [ decodeString modelDecoder msg2 |> Result.toMaybe |> Maybe.withDefault emptyModel |> toString |> H.text ]
]
emptyModel = Model Anonymous 0 0 "" ""
msg1 = """
{
"status": 0,
"message": "Error message explaining what happened in server"
}
"""
msg2 = """
{
"status": 1,
"email_id": "asdfa@asdfa.com"
"token": "asdfaz.adfasggwegwegwe.g4514514ferf"
"id": 234
}
"""
我需要将 JSON 解码为如下所示的榆树类型:
类型
type User = Anonymous | LoggedIn String
type alias Model =
{ email_id : User
, id : Id
, status : Int
, message : String
, accessToken : AccessToken
}
JSON 消息 1
{
"status": 0,
"message": "Error message explaining what happened in server"
}
输入值
Model {
"email_id": Anonymous
, id: 0
, status: 0
, message: json.message
, accessToken: ""
}
JSON 消息 2
{
"status": 1,
"email_id": "asdfa@asdfa.com"
"token": "asdfaz.adfasggwegwegwe.g4514514ferf"
"id": 234
}
输入值
Model {
"email_id": LoggedIn json.email_id
, id: json.id
, status: json.status
, message: ""
, accessToken: json.token
}
解码器信息
以上,"message"并不总是存在,email_id/id/token总是不存在。
如何在 elm 中进行这种类型的条件解码
Json.Decode.andThen
允许您根据字段的值进行条件解析。在这种情况下,看起来你首先要提取 "status" 字段的值, andThen
根据它是 1
还是 [=14= 分别处理它].
编辑 2016-12-15:更新到 elm-0.18
import Html as H
import Json.Decode exposing (..)
type User = Anonymous | LoggedIn String
type alias Id = Int
type alias AccessToken = String
type alias Model =
{ email_id : User
, id : Id
, status : Int
, message : String
, accessToken : AccessToken
}
modelDecoder : Decoder Model
modelDecoder =
(field "status" int) |> andThen modelDecoderByStatus
modelDecoderByStatus : Int -> Decoder Model
modelDecoderByStatus status =
case status of
0 ->
map5
Model
(succeed Anonymous)
(succeed 0)
(succeed status)
(field "message" string)
(succeed "")
1 ->
map5
Model
(map LoggedIn (field "email_id" string))
(field "id" int)
(succeed status)
(succeed "")
(field "token" string)
_ ->
fail <| "Unknown status: " ++ (toString status)
main = H.div []
[ H.div [] [ decodeString modelDecoder msg1 |> Result.toMaybe |> Maybe.withDefault emptyModel |> toString |> H.text ]
, H.div [] [ decodeString modelDecoder msg2 |> Result.toMaybe |> Maybe.withDefault emptyModel |> toString |> H.text ]
]
emptyModel = Model Anonymous 0 0 "" ""
msg1 = """
{
"status": 0,
"message": "Error message explaining what happened in server"
}
"""
msg2 = """
{
"status": 1,
"email_id": "asdfa@asdfa.com"
"token": "asdfaz.adfasggwegwegwe.g4514514ferf"
"id": 234
}
"""