Elm中的解码字典由于额外的反斜杠而失败

时间:2018-11-05 06:47:15

标签: json decode elm

我正在尝试通过dictport发送到javascript以将值存储在localStorage中,并在下次Elm应用通过flag启动时检索它。

下面的代码段显示了通过flag发送的字典以及接收的原始json值。 Json解码失败,在底部显示错误消息。

问题似乎是原始标志值中包含多余的反斜杠(如\“ {\\” Left \\“)。有趣的是,console.log表明传递的flag值javascript是"dict1:{"Left":"fullHeightVerticalCenter","Right":"fullHeightVerticalCenter","_default":"fullHeightVerticalBottom"}"的预期用途,因此Elm似乎添加了额外的反斜杠,但我不知道为什么。而且,我想找到一种更好的方法来实现将字典传递给and来自javascript。

import Json.Decode as JD
import Json.Encode as JE

dict1 = Dict.fromList[("_default", "fullHeightVerticalBottom")
                        , ("Left", "fullHeightVerticalCenter")
                        , ("Right", "fullHeightVerticalCenter")]

type alias FlagsJEValue =
   {dict1: String}

port setStorage : FlagsJEValue -> Cmd msg

-- inside Update function Cmd
setStorage {dict1 = JE.encode 0 (dictEncoder JE.string model.dict1)}

dictEncoder enc dict = 
   Dict.toList dict 
     |> List.map (\(k,v) -> (k, enc v)) 
     |> JE.object 
-- 
type alias Flags =
   {dict1: Dict String String} 

flagsDecoder : Decoder Flags
flagsDecoder =
    JD.succeed Flags
     |> required "dict1" (JD.dict JD.string)

-- inside `init`
case JD.decodeValue MyDecoders.flagsDecoder raw_flags of
   Err e ->
      _ = Debug.log "raw flag value" (Debug.toString (JE.encode 2 raw_flags) )
      _ = Debug.log "flags error msg" (Debug.toString e)

      ... omitted ...

   Ok flags ->
      ... omitted ...


-- raw flag value
"{\n  \"dict1\": \"{\\\"Left\\\":\\\"fullHeightVerticalCenter\\\",\\\"Right\\\":\\\"fullHeightVerticalCenter\\\",\\\"_default\\\":\\\"fullHeightVerticalBottom\\\"}\"\n}"

 --flags error msg

"Failure \"Json.Decode.oneOf failed in the following 2 ways:\\n\\n\\n\\n
(1) Problem with the given value:\\n    \\n    \\\"{\\\\\\\"Left\\\\\\\":\\\\\\\"fullHeightVerticalCenter\\\\\\\",\\\\\\\"Right\\\\\\\":\\\\\\\"fullHeightVerticalCenter\\\\\\\",\\\\\\\"_default\\\\\\\":\\\\\\\"fullHeightVerticalBottom\\\\\\\"}\\\"\\n    \\n    Expecting an OBJECT\\n\\n\\n\\n

(2) Problem with the given value:\\n    \\n    \\\"{\\\\\\\"Left\\\\\\\":\\\\\\\"fullHeightVerticalCenter\\\\\\\",\\\\\\\"Right\\\\\\\":\\\\\\\"fullHeightVerticalCenter\\\\\\\",\\\\\\\"_default\\\\\\\":\\\\\\\"fullHeightVerticalBottom\\\\\\\"}\\\"\\n    \\n    Expecting null\" <internals>”

1 个答案:

答案 0 :(得分:1)

您不需要在那里使用JE.encode

您可以只使用dictEncoder生成Json.Encode.Value并将其直接传递给setStorage

您遇到的问题是,已将dict编码为json字符串(使用JE.encode),然后通过端口发送该字符串,而端口又将该字符串编码为json。您会看到额外的斜杠,因为json字符串是双重编码的。