BWStearns
BWStearns

Reputation: 2706

How to handle cljs-ajax responses?

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)))

Upvotes: 2

Views: 1644

Answers (1)

Timothy Pratley
Timothy Pratley

Reputation: 10662

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)

Upvotes: 5

Related Questions