Search code examples
jsonclojurereactjsclojurescriptreagent

Why does Reagent render JSON in three ways?


I am trying to render JSON data from an API call in Clojurescript/Reagent. When I use js/alert I see the json I expect: ["Sue" "Bob"]

(defn- call-api [endpoint]
  (go
    (let [response (<! (http/get endpoint))]
      (:names (:body response)))))

;; -------------------------
;; Views

(defn home-page []
  [:div (call-api "/api/names")])

This is how I'm referencing the libraries (in case there's an problem there).

(ns myapp.core
    (:require [reagent.core :as reagent :refer [atom]]
              [reagent.session :as session]
              [cljs-http.client :as http]
              [cljs.core.async :refer [<! >!]]
              [secretary.core :as secretary :include-macros true]
              [accountant.core :as accountant])
    (:require-macros [cljs.core.async.macros :refer [go]]))

But when I log it to the console, I get a long hash that looks nothing like the API response. The browser renders "00000000000120".

  • Why do these results differ? (browser, alert window, console message)
  • How can I get what I'm seeing in the alert window to render on the page?

Solution

  • When you call call-api it is going to return a go block. Instead of trying to consume that go block directly in your Reagent function, you could instead update the return value in a ratom.

    (def app-state (atom)) ;; ratom
    
    (defn- call-api [endpoint]
      (go
        (let [response (<! (http/get endpoint))]
          (reset! app-state (:names (:body response))))))
    
    (defn home-page []
      [:div @app-state])
    
    (defn main []
      (call-api))