[英]Decoding Dict in Elm failing due to extra backslashes
I'm trying to send a dict
to javascript via port
for storing the value in localStorage, and retrieve it next time the Elm app starts via flag
. 我正在尝试通过port
将dict
发送到javascript以将值存储在localStorage中,并在下次Elm应用通过flag
启动时检索它。
Below code snippets show the dict sent as well as the raw json value received through flag
. 下面的代码片段显示了已发送的dict以及通过flag
接收的原始json值。 The Json decoding fails showing the error message at the bottom. Json解码失败,在底部显示错误消息。
The issue seems to be the extra backslashes (as in \\"{\\\\"Left\\\\") contained in the raw flag value. Interestingly, console.log
shows that the flag
value passed by javascript is "dict1:{"Left":"fullHeightVerticalCenter","Right":"fullHeightVerticalCenter","_default":"fullHeightVerticalBottom"}"
as intended, so the extra backslashes seem to be added by Elm, but I can't figure out why. Also, I'd be interested to find out a better way to achieve passing a dict to and from javascript. 问题似乎是原始标志值中包含多余的反斜杠(如\\“ {\\\\” Left \\\\“)。有趣的是, console.log
显示javascript传递的flag
值为"dict1:{"Left":"fullHeightVerticalCenter","Right":"fullHeightVerticalCenter","_default":"fullHeightVerticalBottom"}"
按预期使用,因此Elm似乎添加了额外的反斜杠,但我不知道为什么。有兴趣找到一种更好的方法来实现将dict与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>”
You don't need to use JE.encode
there. 您不需要在那里使用JE.encode
。
You can just use your dictEncoder
to produce a Json.Encode.Value
and pass that directly to setStorage
. 您可以只使用dictEncoder
生成Json.Encode.Value
并将其直接传递给setStorage
。
The problem you're encountering it that you've encoded the dict to a json string (using JE.encode
) and then sent that string over a port and the port has encoded that string as json again. 您遇到的问题是,已将dict编码为json字符串(使用JE.encode
),然后通过端口发送该字符串,并且端口再次将该字符串编码为json。 You see extra slashes because the json string is double encoded. 您会看到额外的斜杠,因为json字符串是双重编码的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.