-
Notifications
You must be signed in to change notification settings - Fork 12
Step 05: talking to the server
Browse code - Diff - Live demo
To reset your workspace for this step, run git checkout step-5
.
You will probably need to restart you Figwheel process and install the dependencies. Type ^C in your terminal to stop your Figwheel build process, then run :
lein do deps, clean, figwheel
So far we've been cheating by using a hardcoded list of phones, now let's make our application more realistic by loading the list of phones via HTTP.
Our HTTP server serves the list of phones in JSON format at the path /phones/phones.json
. What we need to do is:
- Send an AJAX HTTP request at
GET /phones/phones.json
- Parse the JSON response into Clojure data structures so we can manipulate them
- When the response arrives, update the state of our application with the list of phones we've just loaded.
As a first change, our atom states now starts with an empty vector of phones :
(defonce state
(rg/atom {:phones []
:search ""
:order-prop :name
}))
Reagent does not provide any way of dealing with AJAX (which is a good thing, a view library should not be concerned with this), so we'll use another ClojureScript library, called cljs-ajax. Let's import this library and require it in our namespace:
project.clj:
:dependencies [;; ...
[cljs-ajax "0.3.14"]
]
core.cljs:
(ns reagent-phonecat.core
(:require ;; ...
[ajax.core :as ajx])
)
We'll write a single load-phones!
function to fetch the phones and put it in our app state:
(defn load-phones! "Fetches the list of phones from the server and updates the state atom with it"
[state]
(ajx/GET "/phones/phones.json"
{:handler (fn [phones] (swap! state assoc :phones phones))
:error-handler (fn [details] (.warn js/console (str "Failed to refresh phones from server: " details)))
:response-format :json, :keywords? true}))
Let's deconstruct this:
- we pass our state atom as a parameter to our function
-
:handler (fn [phones] (swap! state assoc :phones phones))
is the callback that actually updates our state -
:response-format :json, :keywords? true
means "the response will be in JSON, and I want the keys in maps to be keywords (not strings)" -
:error-handler
is the callback that's called when something goes wrong, in this case we'll just log the error and do nothing about it
Finally, we call our function when we initialize our app:
(defn init! []
(load-phones! state)
(mount-root))
We've learned how to use the cljs-ajax
library to make AJAX more practical from ClojureScript.