Fork me on GitHub
Jakub Holý (HolyJak)09:05:41

Is there a way to make a full Fulcro app editable in the browser, something akin CodeSandbox ? Perhaps with Klipse or some of the existing tools? To share interactive, editable demos...

👍 4

Probably the easiest thing to do is to make a server that is running cljs compiler and round-trip it. Bootstrapped cljs would be an option, but would be a lot of work: Fulcro’s macros are not designed to work with bootstrapped cljs, nor do I want another aspect of maintenance on those…you’d have to write your own version of the macros and have those override in bootstrapped mode.


that said, configure-component! is the central component builder, and it is pure cljc, so all you have to do is make a moderately functional version of the macro that outputs calls to that.


then again, it’s the tree of deps that will kill this idea: any libraries that Fulcro uses that have macros (lots and lots of them) will make it intractable. Server round-trip on compile is the best option by far

👍 4

Yea, I’ve been wondering this, klipse might be the easiest unless something already exists? You need to look at how klipse added re-frame functionality I think:


has anyone seen properties that have nil values (coming from the server) not being inserted into the client db even though they are being queried for?

(comp/get-query TaskItem)
=> [:task/id :task/description :task/duration :task/scheduled-at]
(defsc TaskItem [this props]
  {:query [:task/id :task/description :task/duration :task/scheduled-at]
   :ident :task/id
   :initial-state {}})

(defsc TaskList [this {:keys [all-tasks]}]
  {:initial-state {}
   :query         [{[:all-tasks '_] (comp/get-query TaskItem)}]})

(-> (app/current-state SPA) :task/id)

;; the tasks that have missing  :task/scheduled-at  and :task/duration
;; fields are not present on the client
 #uuid"1bdc5d60-34e5-4c97-a30e-d638ee321903" {:task/id #uuid"1bdc5d60-34e5-4c97-a30e-d638ee321903",
                                              :task/description "task 3"}

I confirmed by setting one of their scheduled-at fields and it is making it to the client db.

 #uuid"e0fdda94-5cfe-4062-bf2a-1cdb2521e4f9" {:task/id #uuid"e0fdda94-5cfe-4062-bf2a-1cdb2521e4f9",
                                              :task/description "task 1",
                                              :task/scheduled-at {:duration #time/duration"PT10M", :period nil}},
And this is being returned from the backend (verbose transit copied from chrome devtools):
  [{"~:task/id":"~ue0fdda94-5cfe-4062-bf2a-1cdb2521e4f9","~:task/duration":null,"~:task/description":"task 1","~:task/scheduled-at":{"~:duration":{"~#time/tick":"#time/duration \"PT10M\""},"~:period":null}}
  ,{"~:task/id":"~ucbedb5e7-602b-454d-9b35-5588614c30f0","~:task/duration":null,"~:task/description":"task 2","~:task/scheduled-at":null},
  {"~:task/id":"~uc13695f4-d788-48b5-a578-69d3b3233eab","~:task/duration":null,"~:task/description":"task 3","~:task/scheduled-at":null},
{"~:task/id":"~u51b92cb0-0ef9-46e8-8533-8120b7e6a989","~:task/duration":null,"~:task/description":"task 4","~:task/scheduled-at":null}] ;; ...elided

Jakub Holý (HolyJak)07:05:39

I see doesn't mention anything about nil. It reads > the result does not contain it, then that value is removed perhaps nil is also interpreted in this way? It is I thing considered a good practice to remove keys instead of have them with nil values, Rich mentioned that in a talk and there is even a library for that


thanks for the reply @U0522TWDA I'll try just calling merge! directly with the data and see if i can replicate the issue


it's weird because if i issue the same load! from the repl the data makes it into the app...

Jakub Holý (HolyJak)14:05:53

Ok then the problem must be somewhere else.. Try to find out what is the difference between the two.


It's mostly not an issue because the value will be nil when looked up anyone, but I'm using a generic helper that takes a map of props which only knows the props via using (keys props) I suppose I could pass in a list of keys to the helper, but it's not ideal