I'm building a store website with clojure, reagent, react, and bootstrap. Here is the code for a page.

(ns jimmystore.pages.photo-page 
  (:require
   [reagent.core      :as ra]
   [re-frame.core     :as rf]
   [jimmystore.image-utils :as image-utils]))

;; FIXME make these be the events ones
(rf/reg-sub ::img
  (fn [db _]
    (::img db)))

(rf/reg-sub ::items
  (fn [db _]
    (::items db)))

(def dummy-photo-data {:path "/img/atsui.jpg" ; doing it like this with the intention to pull from server later
                       :title "test"})

(defn photo-card
  ([photo]
   [:div {:class "card
                 col-md-2-5
                 col-5
                 m-md-2
                 m-3"}
    [:img {:src (:path photo)
           :class "card-img-top"}]
    [:div.card-body
     [:h5.card-title (:title photo)]]])

  ([photo title]
   [:div {:class "card
                 col-md-2-5
                 col-5
                 m-md-2
                 m-3"}
    [:img {:src (image-utils/img-blob->img-src photo)
           :class "card-img-top"}]
    [:div.card-body
     [:h5.card-title title]]]))


(defn photos-element [items]
  [:div {:class   "container
                   d-flex
                   flex-wrap
                   align-items-center
                   justify-content-center"}
   (repeat 16 (photo-card dummy-photo-data)) ; grid test
    ;;   (get (first items) :id)
   
    ;;  (photo-card (rf/dispatch [:retrieve-item-picture (get (first items) :id)]) "test") ; grid test 

   ; TODO: logic for inserting objects from backend
   ])

(defn page []
  (ra/with-let [_     (rf/dispatch  [:get-items])
                items (rf/subscribe [:items])]
  [:div{:class "container"}
   [:h3 (str @items "Select a photo.")]
   [photos-element @items]]))

(def page-info {:page-id :photo
                :view   #'page})


(ns jimmystore.events
  (:require
    [re-frame.core :as rf]
    [ajax.core :as ajax]
    [reitit.frontend.easy :as rfe]
    [reitit.frontend.controllers :as rfc]))

;;dispatchers

(rf/reg-event-db
  :common/navigate
  (fn [db [_ match]]
    (def foo match)
    (let [old-match (:common/route db)
          new-match (assoc match :controllers
                           (rfc/apply-controllers (:controllers old-match) match))]
      (assoc db :common/route new-match))))

(rf/reg-fx :common/navigate-fx!
  (fn [[k & [params query]]]
    (rfe/push-state k params query)))

(rf/reg-event-fx :common/navigate!
  (fn [_ [_ url-key params query]]
    {:common/navigate-fx! [url-key params query]}))

(rf/reg-event-db :set-docs
  (fn [db [_ docs]]
    (assoc db :docs docs)))

(rf/reg-event-fx :fetch-docs
  (fn [_ _]
    {:http-xhrio {:method          :get
                  :uri             "/docs"
                  :response-format (ajax/raw-response-format)
                  :on-success       [:set-docs]}}))

(rf/reg-event-fx :test-get-api
 (fn [_ _]
   {:http-xhrio {:method          :get
                 :uri             "/test-get"
                 :response-format (ajax/json-response-format {:keywords? true})
                 :on-success       [:set-docs]}}))

(rf/reg-event-fx :test-post-api
  (fn [_ _]
    {:http-xhrio {:method          :post
                  :uri             "/test-post"
                  :params          {:test-post {:data 1 :foo :bar 2 "ASDASD"}}
                  :format          (ajax/json-request-format)
                  :response-format (ajax/json-response-format {:keywords? true})
                  :on-success      [:no-op]}}))

(rf/reg-event-fx :get-items
  (fn [_ _]
    {:http-xhrio {:method          :get
                  :uri             "/get-items"
                  :response-format (ajax/json-response-format {:keywords? true})
                  :on-success      [:get-items-success]}}))

(rf/reg-event-db :get-items-success
  (fn [db [_ response]]
    (assoc db :items response)))

(defn- get-file-size [file]
  (.-size file))

(defn- get-file-name [file]
  (.-name file))

(defn- get-file-type [file]
  (.-type file))

(rf/reg-event-db :set-file-to-upload
 (fn [db [_ file]]                ;; Local url (for previews etc.)
   (assoc db :upload {:object-url (js/window.webkitURL.createObjectURL file)
                      :file       file
                      :size       (get-file-size file)
                      :name       (get-file-name file)
                      :type       (get-file-type file)})))


(rf/reg-sub :upload
 (fn [db _]
   (-> db :upload)))

(rf/reg-event-db :common/set-error
  (fn [db [_ error]]
    (assoc db :common/error error)))

(rf/reg-event-fx :page/init-home
  (fn [_ _]
    {:dispatch [:fetch-docs]}))

(rf/reg-event-db :no-op
 (fn [db  _]
   db))

;;subscriptions

(rf/reg-sub :common/route
  (fn [db _]
    (-> db :common/route)))

(rf/reg-sub :common/page-id
  :<- [:common/route]
  (fn [route _]
    (-> route :data :name)))

(rf/reg-sub :common/page
  :<- [:common/route]
  (fn [route _]
    (-> route :data :view)))

(rf/reg-sub :docs
  (fn [db _]
    (:docs db)))

(rf/reg-sub :common/error
  (fn [db _]
    (:common/error db)))

(rf/reg-sub :items
  (fn [db _]
    (-> db :items)))

(ns jimmystore.image-utils
  (:require
   [re-frame.core :as rf]
   [ajax.core :as ajax]))

(defn img-blob->img-src
  "Converts an image blobs byte array to a data source for [:img] components"
  [{:keys [content-type byte-array]}]
  (str "data:" content-type ";base64," byte-array))

;; Retrieves an image blob (a map containing content-type and byte-array) by id
;; and calls the on-success-dispatch adding the image blob as the last argument.
;; id                  - id of image
;; on-success-dispatch - re-frame dispatch vector
(rf/reg-event-fx :retrieve-item-picture
  (fn [_ [_ id on-success-dispatch]]
    {:http-xhrio {:method          :get
                  :params          {:id id}
                  :uri             "/retrieve-item-picture"
                  :response-format (ajax/json-response-format {:keywords? true})
                  :on-success      on-success-dispatch}}))



On the photos page, I have the contents of "items" being debug output on the page under the :h3 part as {:items [{:name "32f7a9472d32612126813289780994c5-2.png", :id "59e6f3c5-866c-4d57-8b86-ad7f22188d24", :create-ts "2024-03-20T10:49:05.999Z"} {:name "907a590ace9b4192ebbbab32a9113053.gif", :id "bb6d4cf1-50a3-43af-a2ef-0f9918a0050d", :create-ts "2024-03-20T10:51:56.751Z"} {:name "1436202390320.gif", :id "0ddb5f66-fc58-4a81-8471-03e7419b2853", :create-ts "2024-03-20T11:32:08.534Z"}], :count 3}

I want to get the id of each image in there. When I try to get the contents of :items with (first @items) it returns "object Object". How can I get the ids?