Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manipulate Json.Encode.Value in Elm?

Tags:

json

elm

I'm writing some code to auto-gen JSON codecs for Elm data-structures. There is a point my code, where a "sub-structure/sub-type", has already been encoded to a Json.Encode.Value, and I need to add another key-value pair to it. Is there any way to "destructure" a Json.Encode.Value in Elm? Or combine two values of type Json.Encode.Value?

Here's some sample code:

type alias Entity record =
   { entityKey: (Key record)
   , entityVal: record
   }

jsonEncEntity : (record -> Value) -> Entity record -> Value
jsonEncEntity localEncoder_record val =
  let 
      encodedRecord = localEncoder_record val.entityVal
  in
      -- NOTE: the following line won't compile, but this is essentially
      -- what I'm looking for
      Json.combine encodedRecord (Json.Encode.object [ ( "id", jsonEncKey val.entityKey ) ] )
like image 335
Saurabh Nanda Avatar asked Sep 07 '25 16:09

Saurabh Nanda


1 Answers

You can decode the value into a list of key value pairs using D.keyValuePairs D.value and then append the new field. Here's how you'd do that:

module Main exposing (..)

import Json.Decode as D
import Json.Encode as E exposing (Value)


addKeyValue : String -> Value -> Value -> Value
addKeyValue key value input =
    case D.decodeValue (D.keyValuePairs D.value) input of
        Ok ok ->
            E.object <| ( key, value ) :: ok

        Err _ ->
            input
> import Main
> import Json.Encode as E
> value = E.object [("a", E.int 1)]
{ a = 1 } : Json.Encode.Value
> value2 = Main.addKeyValue "b" E.null value
{ b = null, a = 1 } : Json.Encode.Value

If the input is not an object, this will return the input unchanged:

> Main.addKeyValue "b" E.null (E.int 1)
1 : Json.Encode.Value
like image 69
Dogbert Avatar answered Sep 10 '25 01:09

Dogbert