Search code examples
ajaxclojurescriptreagent

Ajax GET with Reagent


I am doing an Ajax GET from my Reagent application, to load some stuff from the database.

I am not entirely sure what is the best way of getting the result of such ajax call to my page, considering that if I put it in an atom, then Reagent automatically re-renders a component when an atom is dereferenced, which means I get an infinite sequence of ajax calls.

For some code,

(def matches (atom nil))

(defn render-matches [ms]
  (reset! matches (into [:ul] (map (fn [m] ^{:key m}[:li m])
                                   (walk/keywordize-keys (t/read (t/reader :json) ms)))))

This function basically creates a [:ul [:li "Stuff here"] [:li "And here"]]

Which i would like displayed on my page, which now has the following code.

(defn standings-page []
  (GET "/list-matches"
       {:handler render-matches})
  @matches)

Solution

  • I think it's better to save only data in an atom and to generate the HTML as part of the component logic.

    Also it's better to trigger the AJAX call outside the render phase, for example, before the component will mount, or as the result of an event (on-click on a button for example).

    Like this:

    (def matches (atom nil))
    (defn component []
      (let [get-stuff (fn [] (GET "/..." :handler (fn [response] 
                               (reset! matches (:body response))))]
        (get-stuff) <-- called before component mount
        (fn []
          [:ul
            (for [m match]
              ^{:key ...} 
              [:li ...])])))
    

    This is called form-2 in this post.