Search code examples
clojure

Can't extract key from Map


I'm hitting an API that returns some json that I am trying to parse. I look a the keys of the returned parsed values and it says that it has a key "id", but when I try to get the id from the map, I get nothing back.

E.g.:

(require '[clj-http.client :as client]
         '[cheshire.core :refer :all])

(def app-url "http://myapp.com/api/endpoint")
(defn get-application-ids [] (parse-string (:body (client/get app-url))))

(defn -main [] (println (map :id  (get-application-ids))))

This returns (nil nil nil). Which, AFAIKT, it shouldn't - instead it should return the value of the :id field, which is not null.

Helpful facts:

  1. When I run (map keys (get-application-ids)) to find the keys of the returned structure, I get ((id name attempts) (id name attempts) (id name attempts)).
  2. (type (get-application-ids)) returns clojure.lang.LazySeq
  3. (map type (get-application-ids)) returns (clojure.lang.PersistentArrayMap clojure.lang.PersistentArrayMap clojure.lang.PersistentArrayMap)
  4. (println (get-application-ids)) returns (one example of the three returned):
({id application_1595586907236_1211, name myname, attempts [{appSparkVersion 2.4.0-cdh6.1.0, lastUpdated 2020-07-26T20:18:47.088GMT, completed true, lastUpdatedEpoch 1595794727088, sparkUser super, endTimeEpoch 1595794726804, startTime 2020-07-26T20:04:05.998GMT, attemptId 1, duration 880806, endTime 2020-07-26T20:18:46.804GMT, startTimeEpoch 1595793845998}]})

Everything about this tells me that (map :id (get-application-ids)) should return the value of the id field, but it doesn't. What am I missing?


Solution

  • It seems you are using cheshire.core/parse-string. This will return string keys, not keywords. See this example.

    So, it appears that your key is the string "id", not the keyword :id. To verify this theory, try putting in the debugging statement:

    (prn (:body (client/get app-url)))
    

    To ask Cheshire to convert map keys from strings to keywords, use the form

    (parse-string <json-src> true)  ; `true` => output keyword keys
    

    See also this list of documentation sources. Especially study the Clojure CheatSheet daily.