Fork me on GitHub

yes this websocket component looks better 🙂 more questions: - (1) is there an easy migration path from om next to fulcro? - (2) it looks like fulcra can do SSR like om next - is there an example somewhere? In om next I instantiate a reconciler etc. and embed the initial state in the html page (looks fulcra does something similar) - (3) are there ways to manipulate the page from inside the component? Adding css/js dependencies for instance? (there are separate solutions in the react ecosystem like react-helmet, in clj which was made by a former coworker)


3) just helpers for the co-located css stuff as far as I know


Will read - thanks!


Recommendations when Porting from Om Next: 1. You can keep defui, it works, but you’ll have a nicer experience in general if you move towards defsc. The biggest challenge is getting rid of your client-side parser, which you should just aim to do immediately (and our support for InitialAppState means no more hand coding a normalized database…but perhaps you had already realized how to do that in your own Om Next app). The philosophy of Om Next client side parsers cause more complexity than they solve IMO. Great idea, just not great in practice. Render your database as a pure function of db->tree. Use server parsers (esp pathom) to easily reshape your server data to the client needs, and treat things like sorting and filtering as mutations on caches in your app database, not UI-level operations (unless they are super light) or parser layers (which disconnects the logic from the use in ways that are hard to trace). As @U3LP7DWPR said, that is left mostly as a React (or even HTML) exercise. Fulcro say very little about the hard-core DOM (other than CSS injection of co-located component CSS).


So I have two parsers at the moment (one server, one client). I don’t have problems with the initial state since I do SSR (which triggers server parser reads), and populate the inital state in the DOM, which is read on mount by the client. So you are saying client-side parsers should be replaced by server-side db->tree? Not 100% sure I follow, will have to play with the template before understanding what you mean.


I’m saying that Fulcro already sets the client-side parser to essentially db->tree

simple_smile 4

I’m saying that Fulcro encourages you very strongly to abandon the idea of using client-side parsers for the UI, and instead just use a normalized UI database that represents the (normalized version) of the UI graph. I’ve talked about this in many places…in videos, comparisons with Om Next, etc…you should not have to look far for the reasoning…or given your experience I’d bet you already understand the challenges.


@tony.kay I’m running into trouble with trigger-remote-mutation. It seems use :remote for ::uism/mutation-remote even if a different value is set.


Also, are there any known issues between pathom and fulcro.incubator.ui-state-machines?


@levitanong hm. I’d have to look at the mutation remote…it is a synthetic mutation that should be using that for the remote. UI state machiens and pathom have nothing really to do with each other, though of course bad return values from a parser (e.g. your return values) can cause all manner of issues.


Make sure uism is aliased…that would break your remote thing


yeah, it’s aliased


:remote is the default, so if your keyword is wrong for the option, then it will revert


Turn on debug logging…there is a debug statement that says if it sees an explicit mutation remote


I’m looking at fulcro-inspect, and this is one one of the parameters for fulcro.incubator.pessimistic-mutations/start-pmutation: :fulcro.incubator.ui-state-machines/mutation-remote :arcgis


I’ve had to duplicate my :arcgis remote to also be the value of :remote to proceed


Will try the debug logging


One odd thing i noticed: when i run the query in fulcro-inspect:

  "Mutation not found - {:mutation app.api.mutations/hydrate-place-location}"}}


no idea what that is…that all sounds like your code


and you’re not looking for start-pmutation…that is the local side of pmutate…you want mutation-delegate


thing is, it worked without pessimistic-mutations


this particular bit jumps out: {:mutation app.api.mutations/hydrate-place-location} could it be that pessimistic mutates wrap the symbol with an object?


my mutation-delegate has identical parameters as start-pmutation


srorry, I don’t have time to debug this with you. Here is how it works: You do you the trigger, and it builds a “fake” pmutation. It calls pmutate on this handler, basically: The handler is on the real low-level Fulcro multimethod that defmutation emits defmethods for. As you can see on line 730 and 744 it uses the parameterized remote for the remote if it is there, and :remote if not.


lines 738 and such do the rewrite of the AST so it “looks” like the mutation you want to the server


and all of the SM-specific params are stripped out of the AST params there too


line 783 is where it take the symbol of mutation decl and turns it into a parameter


so, if you find an error in any of that, let me know…but that’s how it works


alright, thanks for your time @tony.kay! I’ll digest this.


it always uses the same mutation internally, and that mutation rewrites the server AST for network interaction


@tony.kay Even if the explicit remote is set, all the have remote = :remote, which is what causes the error complaining about an invalid remote :remote:

VM25797:57 explcit remote is  :arcgis
VM25797:57 explcit remote is  :arcgis
VM25797:57 explcit remote is  :arcgis
VM25797:57 explcit remote is  :arcgis
VM25797:57 explcit remote is  :arcgis
VM25797:57 explcit remote is  :arcgis
goog.debug.console.js:203  [104.949s] [fulcro.client.impl.application] Use of invalid remote(s) detected!  #{:remote}
Probe of all-items in fulcro.client.impl.application/detect-errant-remotes:
[ nil]
[ nil]
[:fulcro.history/tx-time 282]
[ "87489027-66b8-43b0-8d57-666ec92a7c83"]
[ false]
[ nil]
[ {}
[:fulcro.client.primitives/ident nil]
[:fulcro.client.primitives/remote :remote] ;; what i'm guessing is causing the issue
[:fulcro.client.primitives/query []]
[ []]
[ :ready]
[ {:tx [
], :ref [:sidebar :root], :reconciler {}
[ nil]
[ false]
[ nil]


feel free to open an issue on incubator with a small repro case

👌 4

I must be doing something wrong. When trying to compile the first thing from the docs in a REPL:`

(ns common.admin.ui.root
   [fulcro.client.dom :as dom :refer [div]]
   [fulcro.client.primitives :as prim :refer [defsc]]))

(defsc Root [this {:keys [root/message]}]
  {:query         [:root/message]
   :initial-state {:root/message "Hello!"}}
  (div :.ui.segments "hello"))
I get a
1. Caused by java.lang.RuntimeException
   No such var: fulcro.client.dom/macro-create-element* What does that mean? I am already off tracks?


if it's cljc you have to require like (ns app.ui (:require #?(:clj [fulcro.client.dom-server :as dom] :cljs [fulcro.client.dom :as dom]))

👍 8

Thanks again!


@nha Om actually has a bug in DOM that makes it inefficient…you can’t make the dom things both functions and macros in the same ns across both langs…it’s a known issue, and Fulcro fixes it, but there is no way around needing conditional requires to make it work right


So, even though it says you’re getting macros for div in the source, if you actually look at the output your getting function calls


You can’t define clj macros AND cljs macros in the same cljc file (if you also need function versions of the same thing)…just can’t be done (with all of the constraints that DOM has…you also NEED function versions, in case you use them as values).

simple_smile 4

well you can check if the macro is supposed to emit CLJS or CLJ code though


so to be more clear: you can’t have function AND macro versions of BOTH clj and cljs thing in one file


f that acts as both a function and macro in one file for both langs


You’re the magician @thheller…but I don’t think that’s a rabbit even you will pull out of a hat 🙂


(I beat my head against a wall for days before asking D. Nolen..since I thought he had written it into Om Next…that’s how I determined what was being done was not written by him, and did not work; well, I had determined that it didn’t work when I tried to write it, I just couldn’t figure out how his did…turned out it didn’t)

😁 4

maybe I missed something


   (defmacro foo [& bar]
     (if (:ns &env)


but this works


that’s fine, yes


now make a function foo that can be used with (apply foo ...)


for both langs


in the same file


yeah that is not possible


exactly 🙂


but it is necessary because you need to be able to use dom things as functions sometimes


but ideally most of the time you get macro expansion for speed


in Om Next, you get functions most of the time because the implementation is wrong


well, I don’t remember under what circumstances…but whatever 🙂


in any case thanks for the explanation 😄


just didn’t want you thinking “well it works in Om Next” 🙂


lol. To be clear, my understanding of Om next is still pretty limited


oh, I thought you were porting an existing Om Next app


I am 😛 not saying it’s a big app or anything. I wrote it, but it is pretty basic


I basically liked the colocated queries and that’s about all I used. That and colocated CSS (I remember making a PR to a precursor to the CSS in fulcro)


ah - looks like dom/render-to-str is gone


oh. dom-server again 🙂


Did you watch any of the videos?