Fork me on GitHub
#fulcro
<
2018-11-20
>
nha12:11:21

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 https://github.com/bluekezza/jet which was made by a former coworker)

claudiu12:11:44

3) just helpers for the co-located css stuff as far as I know http://book.fulcrologic.com/#CSSInjection

nha12:11:07

Will read - thanks!

tony.kay13:11:48

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).

nha17:11:58

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.

tony.kay17:11:10

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

simple_smile 4
tony.kay17:11:28

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.

levitanong14:11:45

@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.

levitanong15:11:11

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

tony.kay15:11:26

@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.

tony.kay15:11:07

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

levitanong15:11:24

yeah, it’s aliased

tony.kay15:11:25

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

tony.kay15:11:23

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

levitanong15:11:14

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

levitanong15:11:45

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

levitanong15:11:53

Will try the debug logging

levitanong15:11:00

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

{app.api.mutations/hydrate-place-location
 {:com.wsscode.pathom.core/reader-error
  "Mutation not found - {:mutation app.api.mutations/hydrate-place-location}"}}

tony.kay15:11:51

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

tony.kay15:11:13

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

levitanong15:11:18

thing is, it worked without pessimistic-mutations

levitanong15:11:58

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

levitanong15:11:40

my mutation-delegate has identical parameters as start-pmutation

tony.kay15:11:18

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: https://github.com/fulcrologic/fulcro-incubator/blob/develop/src/main/fulcro/incubator/ui_state_machines.cljc#L725 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.

tony.kay15:11:56

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

tony.kay15:11:23

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

tony.kay15:11:01

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

tony.kay15:11:13

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

levitanong15:11:14

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

tony.kay15:11:30

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

levitanong17:11:58

@tony.kay Even if the explicit remote is set, all the :fulcro.client.impl.data-fetch/deferred-transaction 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:
[:fulcro.client.impl.data-fetch/initialize nil]
[:fulcro.client.network/abort-id nil]
[:fulcro.history/tx-time 282]
[:fulcro.client.impl.data-fetch/uuid "87489027-66b8-43b0-8d57-666ec92a7c83"]
[:fulcro.client.impl.data-fetch/parallel false]
[:fulcro.client.impl.data-fetch/target nil]
[:fulcro.client.impl.data-fetch/original-env {}
]
[:fulcro.client.primitives/ident nil]
[:fulcro.client.primitives/remote :remote] ;; what i'm guessing is causing the issue
[:fulcro.client.primitives/query [:fulcro.client.impl.data-fetch/deferred-transaction]]
[:fulcro.client.impl.data-fetch/refresh [:fulcro.client.impl.data-fetch/deferred-transaction]]
[:fulcro.client.impl.data-fetch/type :ready]
[:fulcro.client.impl.data-fetch/post-mutation-params {:tx [
(…)
], :ref [:sidebar :root], :reconciler {}
}]
[:fulcro.client.impl.data-fetch/fallback nil]
[:fulcro.client.impl.data-fetch/marker false]
[:fulcro.client.impl.data-fetch/post-mutation fulcro.client.data-fetch/run-deferred-transaction]
[:fulcro.client.impl.data-fetch/field nil]

tony.kay17:11:33

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

👌 4
nha20:11:05

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

(ns common.admin.ui.root
  (:require
   [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*
https://github.com/fulcrologic/fulcro/blob/develop/src/main/fulcro/client/dom.clj#L69 What does that mean? I am already off tracks?

claudiu20:11:06

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
nha20:11:50

Thanks again!

tony.kay20:11:02

@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

tony.kay20:11:32

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

tony.kay20:11:56

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
thheller20:11:39

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

tony.kay20:11:58

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

tony.kay20:11:19

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

tony.kay20:11:54

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

tony.kay20:11:08

(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
thheller20:11:55

maybe I missed something

thheller20:11:02

#?(:clj
   (defmacro foo [& bar]
     (if (:ns &env)
       :cljs
       :clj)))

thheller20:11:06

but this works

tony.kay20:11:10

that’s fine, yes

tony.kay20:11:21

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

tony.kay20:11:23

for both langs

tony.kay20:11:27

in the same file

thheller20:11:34

yeah that is not possible

tony.kay20:11:38

exactly 🙂

tony.kay20:11:53

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

tony.kay20:11:09

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

tony.kay20:11:26

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

tony.kay20:11:47

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

nha20:11:23

in any case thanks for the explanation 😄

tony.kay21:11:00

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

nha21:11:28

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

tony.kay21:11:56

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

nha21:11:18

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

nha21:11:25

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)

nha21:11:41

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

nha21:11:11

oh. dom-server again 🙂

tony.kay21:11:31

Did you watch any of the videos?