hi, I have a first project in Clojure, using the book Living Clojure, where cljs retrieves JSON from the clj server. The code works for me with the cljs-http library, however when I tried substituting js/fetch to get the JSON I couldn’t figure it out, looking for some insight.
Here’s a minimal example with cljs-http (that worked):
I was really trying to follow the example at ClojureScript - Promise interop, but similarly I could get back some kind of Promise related object, but no JSON text.
fetch returns a Promise which will provide the async result. You cannot access the result in a sync fashion. So, with your raw example maybe gets a bit cleaner with fn instead of #(). body is the JSON object result. You can only access it there, not from the init function that called all this.
Thanks very much! That helps wrap my head around it. I got it working, I also realized I needed to convert the JSON body with (js->clj body) to call it as a cljs map.
I’m still curious about the experimental <p! macro in core.async, from this example ClojureScript - Promise interop but I feel like I should understand Promise first…
edit: OK, thanks to your reply I looked at <p! again, and I think my understanding is improving a little. This works:
(ns cheshire-cat.core
(:require [cljs.core.async :refer [go]]
[cljs.core.async.interop :refer-macros [<p!]]))
(defn ^:export init []
(go
(let [response (<p! (js/fetch "cheshire-cat"))]
; JSON endpoint is a map where one of the keys is "status"
(js/alert ((js->clj (<p! (.json response))) "status")))))
Which I think is pretty cool! Though I don’t know how this works with Promise errors etc. I suppose core.async relies on try/catch looking at their example.