What is the best way to parse this on clojurescript

Hello,

Im still at the first challenge of the learn_clojurescript book.
I have managed to get the json back and it looks like this :

hourly: 
   0: 
      dt:  some unix time   
      temp:  xxxx
   1:
     dt :some other unix time  
     temp: xxxxxx

and I need only the 4 first of it.

it it now wise to make a atom which contains a empty map.
and then make some loop from 0 to 3 , take the data out that I need and update the atom so it contains something like this [ 8:00 → 20, 9 → 18] or is there a better way to store the data.

It’s definitely not JSON. Looks more like YAML although indentation is inconsistent and the next to last : placement is confusing.
If that’s indeed YAML that you just typed in by hand, most likely there are JS libraries that can parse it into a JS object that you can then convert into a CLJS object.

I’m not sure why you’d need an atom at all. Store it in a separate binding, or don’t store the initial data at all and just chain it with -> through the relevant processing functions till you get what you want:

(def data (parse-data "..."))
(def transformed-data (transform-data data))

or

(def transformed-data
  (-> "..."
      parse-data
      transform-this
      transform-that))

I need a atom because from what I learned I have to store the data that I want to display on my clojurescript website

So far I learned this and now be challenged to display a 4 hour prediction
but not sure what to change at the atom part to make this work
Code given : Capstone 1 - Weather Forecasting App | Lesson 8 | Learn ClojureScript

I might be wrong, but I’m fairly certain you need an atom because the atom being changed is what triggers a refresh. so, you don’t want to use the atom for your intermediate values because it’ll trigger too many refreshes. parse what you need into its own map and then assign that to the atom when you’re done.

Use js/JSON.parse in order to turn a string of json into a javascript object. Then use js->clj to turn that into a ClojureScript map and pass it the options :keywordize-keys true to turn the strings into keywords. Then you can use select-keys to pull out the key/value pairs that you want. In this case, you want the first for numbers, which were interpreted as keywordized numbers, :0, :1, :2, etc., so we can simply get a (range 4) and turn those into keys that we pass to select-keys.

(def json 
  "{\"hourly\":
    {\"0\":
     {\"dt\": \"some unix time\",
      \"temp\": \"xxxx\"},
     \"1\":
     {\"dt\": \"some other unix time\",
      \"temp\": \"xxxxx\"},
     \"2\":
     {\"dt\": \"some other unix time 2\",
      \"temp\": \"xxxxx\"},
     \"3\":
     {\"dt\": \"some other unix time 3\",
      \"temp\": \"xxxxx\"},
     \"4\":
     {\"dt\": \"some other unix time 4\",
      \"temp\": \"xxxxx\"}}}")

(-> (.parse js/JSON json)

    (js->clj :keywordize-keys true)

    :hourly

    (select-keys (map (comp keyword str) (range 4))))

; => {:0 {:dt "some unix time", :temp "xxxx"}, 
;     :1 {:dt "some other unix time", :temp "xxxxx"}, 
;     :2 {:dt "some other unix time 2", :temp "xxxxx"}, 
;     :3 {:dt "some other unix time 3", :temp "xxxxx"}} 

To @p-himik’s point, you normally wouldn’t want to bring atoms in just to build up state while iterating through a data structure. But once you are done changing your data, by all means lay it to rest in an atom, reactive-atom or db somewhere for future changing.

1 Like