fulcro

Book: http://book.fulcrologic.com, Community Resources: https://fulcro-community.github.io/, RAD book at http://book.fulcrologic.com/RAD.html
Mr. Savy 2020-09-10T00:50:51.347Z

I'm getting the sense that fulcro is better approached from a bottom up perspective if I want to modularize stuff.

Mr. Savy 2020-09-10T00:59:10.347800Z

ok I made an example that sort of captures how I've been thinking about this.

Jakub Holý 2020-09-10T08:29:55.357800Z

Wouldn't the parent component simply get a list of images and map Image Container over it? Normally you would get data from Pathom instead of hardcoding them in initial state. Not sure where you want the images data to be defined, in the parent component?

Jakub Holý 2020-09-10T08:35:12.358Z

Look into the book at the person list example. Isn't it the some, only you query for types of images (ie "dog list" instead of "friends list") and display each via Image Container instead of Person?

Mr. Savy 2020-09-10T22:21:16.371400Z

I figured the parent component would define the source (or get it from its parent) but I think your right. I was looking at the person example last night and I'm pretty sure I'm just thinking about the design wrong. I'll see if I can't get something that resembles the person example

Mr. Savy 2020-09-10T01:11:36.347900Z

(defsc ImageContainer [this {:image-container/keys [id src alt] :as props}]
  {:query [:image-container/id :image-container/src :imag-container/alt]
   :ident :image-container/id
   :initial-state (fn [{:keys [id src alt] :as params}]
                    {:image-container/id id
                     :image-container/src src
                     :image-container/alt alt})}
  ;css/context + add id attr + maybe surround with dom/div or more
  (dom/img {:src src :alt alt}
    ;...
    ))

Mr. Savy 2020-09-10T01:17:42.348100Z

I decided to commit to the image example since I'll have to deal with it eventually. Is this the right sort of approach to building components? If I want to build a container so that all the images have the same shape then this would make sense I think. I could use this in a parent's initial state and pass it the context the parent knows to build the component. The problem though would be the parent's design constraints. I can't make an arbitrary number of image containers and making a large number of them in the parent would get excessive, especially in the initial-state and the parameter list. For example, if the parent is a component that uses, say, four image containers then that's four parameters to add to the header. I need to read up on the data flow after the initial state. Once the initial state is created, what do the parameters and query do for me?

Mr. Savy 2020-09-10T01:24:19.348300Z

yeah the more I think about this the weirder it gets. I have to be thinking about this wrong. So If I define a component that uses a bunch of sub components then that just explodes the size of the initial state since I have to define both what the subcomponent gets and all the components of that sub component and all they get

Mr. Savy 2020-09-10T01:35:30.348600Z

hmm, if I want to deal with that then I could maybe define an instance of a component if I know the data will be mostly or completely static. Very few things on the page actually communicate data so defining instances of compositions of components makes sense.

tony.kay 2020-09-10T02:15:23.348800Z

Computed columns can get complex. There are a number of issues around that which need to be solved, since a computed column might in turn want to deal with data that is naturally nested…for example, you might say “I have three line items on this order, so I’d like to be able to query for the line items in this column, but display a total that is computed”. The options are kind of endless. That said: computed colums *are possible with the current design: Add an attribute to your model with whatever type you want the column to have. It doesn’t matter that the server will respond to it with nothing. Add that column to your report. Set the field-formatter for that column. That function will receive the report instance, the row props, etc. You can make up whatever you want for that column.

tony.kay 2020-09-10T02:15:49.349Z

So, I think that case you’re pointing out is already supported.

tony.kay 2020-09-10T02:17:39.349400Z

What we need is improved docs 😄

➕ 1
tony.kay 2020-09-10T03:03:28.349700Z

I’m happy to announce the release of Fulcro 3.2.16. This version adds a new plugin to support completely synchronous operation (sans remotes) which can be used to improve regular application performance, but can also be used to enable trivial full-app testing that has no asynchrony even in js. It also removes some internal debugging logic that was unnecessary and affected dev-time performance. See the new chapter in the book at: http://book.fulcrologic.com/#_synchronous_operation https://github.com/fulcrologic/fulcro

tony.kay 2020-09-10T03:04:00.350400Z

Thanks to the Folks at Dataico for funding this cool addition: @pvillegas12 @dansudol

🔥 8
tony.kay 2020-09-10T03:05:22.351Z

Be sure and check out the cool new testing abilities this adds: http://book.fulcrologic.com/#_testing_full_apps_using_synchronous_operation

tony.kay 2020-09-10T03:06:41.352600Z

BTW, that testing works in CLJC…I’ve gotten in the habit of writing all of my Fulcro code in CLJC (which is only slightly painful in UI…just stub all the low-level js stuff out with #?(:cljs …) ). This lets me run all of my tests in a normal Clojure REPL with a simple kb shortcut, which is very nice since the CLJ runners are much more full-featured.

2020-09-10T04:21:42.353900Z

Just cloned the fulcro-rad datomic-cloud branch from the repo and ran the recommended commands. I’m visiting the http server at 8081 but I’m only seeing a blank, brown page. Is that expected?

✅ 1
2020-09-10T04:26:58.354100Z

[:main] Compiling ...
------ WARNING #1 -  -----------------------------------------------------------
 Resource: node_modules/semantic-ui-react/dist/commonjs/lib/AutoControlledComponent.js:219:2
 JSDoc annotations are not supported on return.
--------------------------------------------------------------------------------

Adrian Smith 2020-09-10T08:21:21.357400Z

Sounds like an issue in semantic ui itself which is a javascript ui library, should be safe to ignore but if not maybe try bumping the version on it?

Tyler Nisonoff 2020-09-10T04:40:43.355200Z

It should be port 3000 8081 is the shadow http server but it’s not used in the demo repo

2020-09-10T04:53:59.355400Z

Isn’t that 9630?

2020-09-10T04:54:26.355900Z

I was wrong, you are right

Tyler Nisonoff 2020-09-10T04:54:44.356200Z

There’s the server and the http dev server

Tyler Nisonoff 2020-09-10T04:54:52.356700Z

But the Fulcro backend is on 3000

👍 1
tony.kay 2020-09-10T17:29:28.364300Z

So I just did some performance/behavioral analysis on the differences between the standard tx processing and the new pluggable synchronous version. Of course they both do roughly equivalent work, so the overall CPU usage is roughly equivalent, but here is an example of where your end users would experience differences. The scenario is the full-stack TodoMVC app, where an item is being added to the list. This involves: • An optimistic update to add the item to the list • A network request to add it on the server • A server response (which could result in data changes..tempid remapping, etc.) • A secondary render to update the view based on the server result The old tx processing does everything asynchronously, and schedules animations using requestAnimationFrame. The result looks like this in a flame chart:

tony.kay 2020-09-10T17:29:35.364400Z

tony.kay 2020-09-10T17:30:06.365300Z

Notice the network request at the top. The overall time from where the user presses “Add” to the final network result refresh is about 81ms.

tony.kay 2020-09-10T17:30:19.365700Z

The new synchronous tx processing on the same interaction looks like this:

tony.kay 2020-09-10T17:30:27.365800Z

tony.kay 2020-09-10T17:31:58.367900Z

Notice the network request starts while the initial tx processing is still running, and actually completes before the final DOM refresh of the keypress (7ms), triggering the UI update for the network result. Total time from keypress to completion of final render after network interaction: 15ms. Again, no CPU overhead difference…they both consume the same processing time; however, the new one feels like 60fps with full stack, whereas the old one feels more like 10fps.

tony.kay 2020-09-10T17:33:18.369200Z

So, not only does the new tx processing make for interesting sync testing possibilities, it leads to dramatically improved user perception of “snappiness” in full-stack scenarios.

👍 6
❤️ 2
🚀 3
daniel.spaniel 2020-09-10T18:58:01.369900Z

f-in-a .. its so good .. wow

cqautomatic 2020-09-10T20:35:54.371Z

Nice!