2016-05-11 6 views
2

ich eine JSON bin erhalten, die wie folgt aussieht:Elm: JSON-Decoder, konvertieren String Bool

{ name: "NAME1", value: "true" } 

Ich möchte einen json Decoder schaffen, die einen Datensatz wie dies schaffen würde:

{ name: "NAME1", value: True } 

Ich versuche, einen Decoder zu machen, der "True" in True verwandelt. Ich tat das so weit:

userProperties : Json.Decode.Decoder Props 
userProperties = 
    Json.Decode.object2 (,) 
    ("name" := Json.Decode.string) 
    ("value" := Json.Decode.string) 
     `andThen` \val -> 
     let 
      newVal = -- Do something here? 
     in 
      Json.Decode.succeed <| newVal 
+0

Sie haben 'val' denen sollte' "true" 'in Ihrem Beispiel sein, so das Schreiben der Die Zuweisung zu 'newVal' sollte ziemlich trivial sein, abhängig von genau der gewünschten Semantik - möglicherweise nur ein' if' Ausdruck. Was ist das Problem, das du hast, wenn du es herausgefunden hast? –

Antwort

8

Es gibt ein paar Probleme in Ihrem Beispiel, so lassen Sie uns durch jeden von ihnen gehen.

Sie haben nicht die Definition von Props so gezeigt Ich gehe davon aus, basierend auf dem Beispiel, dass es das ist:

type alias Props = { name : String, value : Bool } 

Sie passieren (,) als erstes Argument zu object2 die angibt, dass Sie einen Decoder vom Typ Tupel zurückgeben werden. Das sollte wohl sein:

Json.Decode.object2 Props 

Nun wird die Art und Weise Sie andThen verwenden, werden nicht wegen ihrer Rangordnung kompilieren. Wenn Sie die ganze Sache klammern, würde es so aussehen:

userProperties = 
    (Json.Decode.object2 Props 
    ("name" := Json.Decode.string) 
    ("value" := Json.Decode.string)) 
     `andThen` \val -> 
     let 
      newVal = -- Do something here? 
     in 
      Json.Decode.succeed <| newVal 

, die nicht korrekt sein wird, da das, was Sie wollen andThen die Zeichenfolge "true" im "value" Feld ist. Um das zu tun, würde ich empfehlen, einen Decoder zu schaffen, die die boolean Decoder bieten:

stringBoolDecoder : Json.Decode.Decoder Bool 
stringBoolDecoder = 
    string `andThen` \val -> 
    case val of 
     "true" -> succeed True 
     "false" -> succeed False 
     _ -> fail <| "Expecting \"true\" or \"false\" but found " ++ val 

ich nur bei der Handhabung von "false" und dem Erraten catch-all unterstreichen. Ändern Sie die Implementierung entsprechend Ihrem Geschäftsfall.

Beim Aufbau von komplexen Decodern ist es oft am besten, Decoder-Definitionen in den kleinsten Brocken aufzuteilen, wie oben beschrieben.

Schließlich können wir jetzt Ihre userProperties Decoder neu definieren die stringBoolDecoder an der entsprechenden Stelle zu verwenden:

userProperties : Json.Decode.Decoder Props 
userProperties = 
    Json.Decode.object2 Props 
    ("name" := Json.Decode.string) 
    ("value" := stringBoolDecoder) 
+1

Große Antwort! Ich verbinde langsam die Punkte mit dem FP-Ansatz. –