How to Encode a dict?

I’m trying to Encode a model that is using a dict attribute but I don’t know how to encode that parte of the model, I’m trying to do the following.

type alias TemplateResponses =
{ userId : String
, name : String
, testResponses : List TestResponse
}

type alias TestResponse =
{ name : String
, responses : List Response
}

type alias Response =
{ id : String
, response : Dict Int String
}

emptyTemplateResponse : TemplateResponses
emptyTemplateResponse =
{ userId = “234”
, name = “”
, testResponses = []
}

templateResponseEncoder : TemplateResponses -> Encode.Value
templateResponseEncoder templateResponse =
Encode.object
[ ( “userId”, Encode.string templateResponse.userId )
, ( “uid”, Encode.string templateResponse.name )
, ( “testResponses”, Encode.list testResponseEncoder templateResponse.testResponses )
]

testResponseEncoder : TestResponse -> Encode.Value
testResponseEncoder testResponse =
Encode.object
[ ( “name”, Encode.string testResponse.name )
, ( “responses”, Encode.list responseEncoder testResponse.responses )
]

responseEncoder : Response -> Encode.Value
responseEncoder response =
Encode.object
[ ( “id”, Encode.string response.id )
, ( “response”, Encode.dict response.response)
]

but i receive the next error
The 2nd element is a tuple of type:
( String, #(v -> Encode.Value) -> Dict k v -> Encode.Value# )
But all the previous elements in the list are:
( String, #Encode.Value# )

You need to pass 3 arguments to Encode.dict, the 1st is a function to convert the key to string, the 2nd is the value encoder, and the third is the dict.
https://package.elm-lang.org/packages/elm/json/latest/Json-Encode#dict

Thanks for your commend, but I really don’t get it
I wrote the next code and It seems like everything is ok :

responseEncoder : Response -> Encode.Value
responseEncoder response =
Encode.object
[ ( “id”, Encode.string response.id )
, ( “response”, Encode.dict identity Encode.string response.response)
]

but what does mean identity?

identity is a function defined as identity a = a. It basically just returns its argument.

This is needed because Dict in elm can have comparable keys BUT the encoded dictionary keys must be String (you can’t have a javascript object field name be a tuple of Int). In your case, the keys are already String so, you don’t need to transform them so you use identity to just pass them through.

Actually my original key was an Int but I changed it to String because that was the only way to remove the error, but if I wanted to use an Int key I need to make a function that receipted all my keys in Int and return them in String?

You use String.fromInt instead of identity and you should be OK.

1 Like

ohhh I see, you’re totally right. thanks man, have a nice day.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.