Search code examples
jsonclojuretype-conversionedn

How to convert JSON to EDN in Clojure?


I think this is a simple question but as a beginner in Clojure, I would like to convert a simple JSON to EDN in Clojure.

My JSON:

{
    "Data": [
        {
            "Metadata": {
                "Series": "1/2"
            },
            "Hybrid": {
                "Foo": 76308,
                "Bar": "76308",
                "Cat": "Foo123"
            }
        }
    ],
    "Footer": {
        "Count": 3,
        "Age": 0
    }
}

So if we assume that data is the json above, I have tried to convert it to an EDN using Cheshire like so:

(log/info "data" (cheshire.core/parse-string {(data) true}))

However, whenever I run this bit of code, I get the error message:

ERROR compojure.api.exception - clojure.lang.PersistentArrayMap cannot be cast to java.lang.String

I think I am getting this because my JSON is not a string, but unsure if I first need to convert it to a string, and then converting to EDN - or if there is a way I can go straight from JSON to EDN?

Thank you for your help in advance


Solution

  • You get this error for this line:

    (cheshire.core/parse-string {(data) true})
    

    What is happening here:

    1. Whatever your data is, it seems to be call-able - or else (data) would already fail. E.g. with ("{}") will give you an class java.lang.String cannot be cast to class clojure.lang.IFn error. Also it's unlikely, that data is already the de-serialized map, as maps are functions, but have an arity of at least one. So we have to assume, that data is actually a function and returns whatever.
    2. Next this result of this call is put into a new map, as key and the value true ({? true}).
    3. Then this map is passed to cheshire's parse-string, but this clearly is no string, but a map, hence the error.

    Given all that, and assuming, that (data) returns a String, your best bet is:

    (cheshire.core/parse-string (data))
    

    And if you really want the EDN for that, that would be:

    (pr-str (cheshire.core/parse-string (data)))