I have an json response and would like to get the values out:
(cheshire.core/parse-string (:body picList))
{"photoset" {"primary" "8455893107", "total" "1", "pages" 1, "perpage" 500, "page" 1,
"per_page" 500, "photo" [{"id" "8455893107", "secret" "1a3236df06", "server" "8087",
"farm" 9, "title" "IMG_0137", "isprimary" "1"}], "owner" "93029076#N07", "id"
"72157632724688181", "ownername" "clojureB5"}, "stat" "ok"}
How can I get the different values like photoset->primary or photoset->photo->id ?
I tried something with (map #(get % "photoset")... but it doest work.
Thanks!
I think you're looking for clojure.core/get-in
(get-in your-parsed-json ["photoset" "primary"]) ;; "8455893107"
(-> (get-in your-parsed-json ["photoset" "photo"])
first
(get "id")) ;; "8455893107"
(get-in your-parsed-json ["photoset" "photo" 0 "id"]) ;; "8455893107"
Related
I am new to clojure. I have a map fooBar :
#js {:foo 1, :bar 2}
I want to get foo. I have tried :
(:foo fooBar)
(get fooBar :foo)
The answer turned out to be simple field access :
(.-foo fooBar)
I'm trying to pass a clojurescript map to a webworker.
Before I pass it, it is of type PersistentArrayMap.
cljs.core.PersistentArrayMap {meta: null, cnt: 3, arr: Array(6), __hash: null, cljs$lang$protocol_mask$partition0$: 16647951…}
However, when it gets to the worker, it's just a plain old Object
Object {meta: null, cnt: 3, arr: Array(6), __hash: null, cljs$lang$protocol_mask$partition0$: 16647951…}
with the data seemingly intact. At this point I'd like to turn it back into a PersistentArrayMap so that I can work with it in cljs again.
Using clj->js and js->clj doesn't really work because it doesn't distinguish between keywords and strings, so some data is lost.
What's the best way to handle this situation? It's possible that I'm going about this in the entirely wrong way.
The built-in solution is to serialize the data to EDN and reading it back. clj->js is inherently lossy and should be avoided.
You start by turning the object into a string and send that over to the worker.
(pr-str {:a 1})
;; => "{:a 1}"
In the worker you read it back via cljs.reader/read-string
(cljs.reader/read-string "{:a 1}")
;; => {:a 1}
This will usually be good enough but the transit-cljs library will be slightly faster. Depending on the amount of data you plan on sending it may be worth the extra dependency.
Did you use keywordize-keys in the code?
(def json "{\"foo\": 1, \"bar\": 2, \"baz\": [1,2,3]}")
(def a (.parse js/JSON json))
;;=> #js {:foo 1, :bar 2, :baz #js [1 2 3]}
(js->clj a)
;;=> {"foo" 1, "bar" 2, "baz" [1 2 3]}
(js->clj a :keywordize-keys true)
;;=> {:foo 1, :bar 2, :baz [1 2 3]}
Full documentation is here.
I am new Clojurescript and want to hack arround with clojurescript and electron based on an small json file.
I am doing something like (with transit/cljs)
(def jsondata (t/read (t/reader :json) (.readFileSync fs path_to_file "utf8")))) )
first I check if status is ok, that works fine...
(let [json_status (get jsondata "status")]
(.log js/console "JSON Glossar Status:" json_status))
now, how can I access one of the maps in the pages array, or step through the map?
{"status":"ok",
"pages":[
{
"id":1,
"name":"name1",
"image":"imagename1.png",
"children":[
{
"id":1,
"copytext":"kdjsldjsljfl"
},
{
"id":2,
"copytext":"dksdöfksöfklsöf"
}
]
},
{
"id":2,
"name":"name1",
"image":"imagename1.png",
"children":[
{
"id":4,
"copytext":"kdjsldjsljfl"
},
{
"id":5,
"copytext":"dksdöfksöfklsöf"
}
]
}
]
}
You can use aget (i.e. "array get") for nested ClojureScript / JavaScript interop.
For example, if you wanted to access the second map item in your "pages" array, you could do this:
(def my-js-object
(clj->js {:status "ok"
:pages [{:id 1
:name "foo"
:children []}
{:id 2
:name "bar"
:children []}]}))
(aget my-js-object "pages" 1)
In the above code I'm simply using clj->js to construct a notional (and incomplete) representation of your JSON; I hope this is enough to make sense.
My REPL output was:
#js {:id 2, :name "bar", :children #js []}
If you wanted to do something more complex with each page item, e.g. "map over each page hashmap and pull out the name values", then you could make use of the .- JS property accessor
(->> (.-pages my-js-object)
(map #(.-name %)))
REPL output:
("foo" "bar")
To not answer the question, you could use
js->cljs, https://cljs.github.io/api/cljs.core/js-GTclj, to turn your json into a normal Clojure data structure and use Clojures normal fns to extract the data you want.
I'm using Clj Json library to parse JSON data in clojure. How do i access all the values itertively and print it in a text file?
I have read the JSON. Can someone help me in parsing it and writing it to a text file?
def all-records (json/read-json (slurp "file.json")));
(println all-records);
(println (get-in all-records [:entry]))
Update:
Here is a sample json file :
{"markers" : [{"point" :new GLatLng (40.266044, -74.718479),
"homeTeam" : "Lawrence Library",
"awayTeam" : "LUGip",
"markerImage" : "images/red.png",
"information" : "Linux users group meets second Wednesday of each month.",
"fixture" : "Wednesday 7pm",
"capacity" : "",
"previousScore" : ""},
{"point" :new GLatLng (40.211600, -74.695702),
"homeTeam" : "Hamilton Library",
"awayTeam" : "LUGip HW SIG",
"markerImage" : "images/white.png"]}
If you put the json in a file like so:
{"markers" : [{"point" :new GLatLng (40.266044, -74.718479),
"homeTeam" : "Lawrence Library",
"awayTeam" : "LUGip",
"markerImage" : "images/red.png",
"information" : "Linux users group meets second Wednesday of each month.",
"fixture" : "Wednesday 7pm",
"capacity" : "",
"previousScore" : ""},
{"point" :new GLatLng (40.211600, -74.695702),
"homeTeam" : "Hamilton Library",
"awayTeam" : "LUGip HW SIG",
"markerImage" : "images/white.png"]}
and then write a little code:
(ns ...
(:require [cheshire.core :as cc] ...))
(def json-data (slurp "resources/sample.json"))
(defn json->clj [arg]
"Shortcut to cheshire.core/parse-string"
(cc/parse-string arg true)) ; true => keywordize-keys
(pprint (json->clj json-data))
you get an error
Error refreshing environment: com.fasterxml.jackson.core.JsonParseException:
Unrecognized token 'new': was expecting 'null', 'true', 'false' or NaN
The problem is the 2 occurrances of new GLatLng (40.266044, -74.718479) in the JSON data. JSON data is only data, like strings & numbers. You cannot have a function call (in this case a constructor call) embedded in the JSON.
I have a problem parsing json data in a loop. Iam a clojure beginner and need some hint for looping through json data.
The data looks like this:
{"photoset" {"primary" "8455893107", "total" "2", "pages" 1, "perpage" 500, "page" 1,
"per_page" 500, "photo"
[{"id" "8455893107", "secret" "1a3236df06", "server" "8087",
"farm" 9, "title" "IMG_0137", "isprimary" "1"}
{"id" "8469482476", "secret" "4c1bf59214",
"server" "8235", "farm" 9, "title" "HippieBus", "isprimary" "0"}]
, "owner"
"93029076#N07", "id" "72157632724688181", "ownername" "clojureB5"}, "stat" "ok"}
What I want to do is loop through the two photos and build a new url with the id and farm value like http://www.flickr.com/farm/id
I know that I can get one value like this:
(-> (get-in (cheshire.core/parse-string (:body picList)) ["photoset" "photo"]) first (get "id"))
But I can I now loop through it?
You can simply use map.
(->> (get-in data ["photoset" "photo"])
(map #(str "http://www.flickr.com/" (get % "farm") "/" (get % "id"))))
It will yield the following list:
("http://www.flickr.com/9/8455893107" "http://www.flickr.com/9/8469482476")