Skip to content

Instantly share code, notes, and snippets.

@zeitstein
Last active December 20, 2021 10:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeitstein/21257931fea29c1d0e737705a02f1bb2 to your computer and use it in GitHub Desktop.
Save zeitstein/21257931fea29c1d0e737705a02f1bb2 to your computer and use it in GitHub Desktop.
Reproducing unexpected denormalization behaviour with infinitely recursive queries
(ns app.gist
(:require
[com.fulcrologic.fulcro.application :as app]
[com.fulcrologic.fulcro.components :as comp :refer [defsc]]
[com.fulcrologic.fulcro.dom :as dom :refer [div h3 span]]
[com.fulcrologic.fulcro.algorithms.merge :as merge]
[com.fulcrologic.fulcro.algorithms.denormalize :as de]))
(declare ui-folder)
(defsc Folder [_ {:keys [id data children]}]
;; note: using a recursion limit fixes the issue
{:query [:id :data {:children '...}]
:ident :id}
(div {:style {:marginLeft "20px"}}
(span (str "id: " id " | data: " data))
(when children
(div
(map ui-folder children)))))
(def ui-folder (comp/computed-factory Folder {:keyfn :id}))
(defsc RootFolder [_ {:keys [id data children]}]
{:query [:id :data {:children (comp/get-query Folder)}]
:ident :id}
(div
(h3 (str "id: " id " | data: " data))
(when children
(map ui-folder children))))
;; note: using ignored forms (just namespacing root's attributes) fixes the issue
#_(defsc RootFolder [_ {:root/keys [id data children]}]
{:query [:root/id :root/data {:root/children (comp/get-query Folder)}]
:ident :root/id}
(div
(h3 (str "id: " id " | data: " data))
(when children
(map ui-folder children))))
(def ui-root-folder (comp/factory RootFolder {:keyfn :id}))
(defsc UI [_ {:keys [main-tree]}]
{:query [{:main-tree (comp/get-query RootFolder)}]}
(when main-tree
(ui-root-folder main-tree)))
(defonce APP (app/fulcro-app))
(defn ^:export init []
(app/mount! APP UI "app")
(merge/merge-component! APP RootFolder
{:id "root"
:data "Home"
:children [{:id "1", :data "Folder 1"}
{:id "0"
:data "Folder 0"
:children [{:id "1", :data "Folder 1"}]}]}
:replace [:main-tree])
;; I want/expect to see this same structure in the UI, i.e.
;; Home
;; - Folder 1
;; - Folder 0
;; - - Folder 1 (<-- this is missing from db->tree and UI)
#_(merge/merge-component! APP RootFolder
{:root/id "root"
:root/data "Home"
:root/children [{:id "1", :data "Folder 1"}
{:id "0"
:data "Folder 0"
:children [{:id "1", :data "Folder 1"}]}]}
:replace [:main-tree]))
(defn ^:export refresh [] (app/mount! APP UI "app"))
(comment
;; one can see the issue originates here: Folder 0 has an empty vector for :children
(de/db->tree (comp/get-query UI)
(app/current-state APP)
(app/current-state APP)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment