问题
I am making a request from a clojurescript frontend with cljs-ajax to an API that responds with JSON but it seems like I need to do something to it before I can use it in cljs.
(defn all-pieces []
(GET "/art/pieces" {:handler ajax-success-handler}))
When I initialize my app-state I assign the key :all-pieces (all-pieces)
When I go to iterate over :all-pieces
in a component I get the error Uncaught Error: [object Object] is not ISeqable
.
(defn pieces-component []
[:ul (for [piece (:all-pieces @app-state)]
[:li (art-piece piece)])])
Edited re Pratley:
The code below now results in the state of all-pieces
being {}
, see anything wrong?
;; -------------------------
;; Remote Data
(defn all-pieces [handler]
(GET "/art/pieces" {:handler handler}))
;; -------------------------
;; State Management
(def app-state (atom
{:doc {}
:saved? false
:page-state {}
:all-pieces {}}))
(defn set-pieces-fresh []
(all-pieces (fn [pcs] swap! app-state assoc :all-pieces pcs)))
回答1:
Don't set :all-peices
to the result of (all-pieces)
.
The function ajax-success-handler
should set :all-peices
instead.
The result of (all-pieces)
is the result of starting the asynchronous call, not the response. The handler is what gets called when the response arrives.
(fn [pcs] swap! app-state assoc :all-pieces pcs)
Does not do any swapping, as swap! needs to be in parens... it is just a function that returns pcs. Consider promoting it to a named function so you can test it separately:
(def app-state
(atom {:all-pieces {}}))
(defn pieces-handler [pcs]
(swap! app-state assoc :all-pieces pcs))
(defn fetch-pieces []
(GET "/art/pieces" {:handler pieces-handler}))
(fetch-pieces)
来源:https://stackoverflow.com/questions/35906629/how-to-handle-cljs-ajax-responses