Reputation: 2181
Say I have a component which needs to request some data from server before rendering.
What I have now is something like with cljs-ajax
library:
(def data (r/atom nil))
(defn component [id]
(r/create-class {:reagent-render simple-div
:component-did-mount (partial get-data id)}))
(defn get-data [id]
(GET (str "/api/" id)
{:handler init}))
(defn init [response]
(let [data1 (:body response)
data2 (compute data1)
data3 (compute2 data2)]
(reset! data (compute3 data1))
(.setup @data data1)
(.setup2 @data data2)
(.setup3 @data data3))
the setup
functions are some foreign JS library functions with side effects.
This works but I don't feel like this is the correct way to do callback.
Not to mention if I need to GET
other datas based on the first data I got, and then other datas based on that, it would be a very nasty chain of callbacks.
Is there a better, clean way of doing this kind of ajax request in reagent/clojurescript?
Upvotes: 12
Views: 6142
Reputation: 10662
The most common way to make requests is cljs-http. Add [cljs-http "0.1.39"]
to the dependencies in project.clj
and restart the figwheel process in the terminal to pick up the new dependency.
(ns my.app
(:require
[cljs.core.async :refer [<!]] [cljs-http.client :as http])
(:require-macros [cljs.core.async.macros :refer [go]])
(go (let [response (<! (http/get "data.edn"))]
(prn (:status response))
(prn (:body response))))
Cljs-http is a nice way to manage HTTP requests. It uses core.async channels to deliver its results. For now, all you need to focus on is that http/get and http/post calls should occur inside a go form, and the result is a channel that can have its result read with
Dependent http gets can be chained together in a sensible way in a single go block that looks like sequential code, but occurs asynchronously.
Upvotes: 13