Ошибка декодирования Dict в Elm из-за дополнительной обратной косой черты - PullRequest
0 голосов
/ 05 ноября 2018

Я пытаюсь отправить dict в javascript через port для хранения значения в localStorage и получить его при следующем запуске приложения Elm через flag.

Ниже фрагменты кода показывают отправленный dict, а также необработанное значение json, полученное через flag. Не удается декодировать Json, показывая сообщение об ошибке внизу.

Похоже, проблема заключается в дополнительных обратных слешах (как в \ "{\\" Left \\ "), содержащихся в необработанном значении флага. Интересно, что console.log показывает, что значение flag, переданное JavaScript, равно "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>”

1 Ответ

0 голосов
/ 05 ноября 2018

Вам не нужно использовать JE.encode там.

Вы можете просто использовать dictEncoder для получения Json.Encode.Value и передать его непосредственно setStorage.

Проблема, с которой вы столкнулись, заключается в том, что вы закодировали dict в строку json (используя JE.encode), а затем отправили эту строку через порт, и порт снова закодировал эту строку как json. Вы видите дополнительные косые черты, потому что строка json имеет двойную кодировку.

...