fulcro

Book: http://book.fulcrologic.com, Community Resources: https://fulcro-community.github.io/, RAD book at http://book.fulcrologic.com/RAD.html
tony.kay 2020-12-15T00:46:40.435200Z

@holyjak thanks for those…I’d appreciate gathering up a few in the future and submitting one PR 🙂

1👍
tony.kay 2020-12-15T00:47:39.435400Z

published changes

tony.kay 2020-12-15T00:48:34.435500Z

defrouter’s body is optional, is a render, and should not side-effect…so confused what you mean

tony.kay 2020-12-15T00:49:08.435700Z

perhaps book has confusing text?

JAtkins 2020-12-15T01:36:00.438500Z

Can rad forms be targeted? person has an address, but allow a button on the person line item that says add address, which routes you to only the Address form, and leaves all ui for person out.

JAtkins 2020-12-15T01:36:47.439100Z

Looking at the source makes me think no, but I'm kinda hoping that I'm just missing the support 🙂

tony.kay 2020-12-15T03:13:40.439900Z

@jatkin yes

tony.kay 2020-12-15T03:14:02.440500Z

sorta…depends on what direction the association is modelled

tony.kay 2020-12-15T03:14:19.441Z

or you can agument save middleware to fix it up

JAtkins 2020-12-15T03:14:46.442100Z

Oh, Gacha. it would need middleware in this case if I understand correctly

JAtkins 2020-12-15T03:15:00.442800Z

If person had a ref to addresses

tony.kay 2020-12-15T03:15:08.443Z

1. Add a virtual (fake) attr to address as :address/person 2. Send it to the form as initial state 3. In save middleware, capture the fake and rewrite it

JAtkins 2020-12-15T03:15:29.443600Z

Cool, sounds like a plan

tony.kay 2020-12-15T03:15:36.443800Z

you’d make a special instance of address for that, since it would have to declare that as a field

tony.kay 2020-12-15T03:15:40.444100Z

and you’d just hide that field

tony.kay 2020-12-15T03:15:49.444300Z

should work

JAtkins 2020-12-15T03:19:21.446700Z

Cool. Do you keep a list of tips like this anywhere? If not it may be worthwhile to monitor this channel and compile stuff like this from you and others on the channel into a big fqa.

tony.kay 2020-12-15T03:21:42.447100Z

nope

tony.kay 2020-12-15T03:22:14.447600Z

I would love to have more time to document the project, but I don’t 😞

JAtkins 2020-12-15T03:24:07.448700Z

I’ll start watching and compiling stuff like this. I’ll try to tag stuff as I go. Maybe it will be useful :).

JAtkins 2020-12-15T03:24:22.449100Z

I’ll put it in a gh repo

Brian Abbott 2020-12-15T03:27:14.449800Z

Just putting some feelers out - is there anyone that might be interested in doing a meetup presentation on Fulcro?

stuartrexking 2020-12-15T04:01:09.450Z

🙏:skin-tone-2:

JAtkins 2020-12-15T06:06:30.450700Z

w.r.t? Most likely.

Alex Piers 2020-12-15T07:55:09.485900Z

In the process of digging into all the Fulcro materials and would like to share a few thoughts, hopefully helpful to those who are also dipping their toes in Fulcro. Though I've found the videos and the developer guides to be an excellent source of information, the learning curve is very slow at the beginning especially if you do not have prior knowledge on Om Next (not to mention React and GraphQL). However, it is definitely an increasing-returns learning curve when you truly get the point of Fulcro's design. The things that helped me get Fulcro is the Fulcro2 videos which filled in many blanks and guided me to explore Untangled and Om Next. Interestingly, the unlisted and supposedly outdated videos are the most useful. These gems are not easy to find. I only found them while going through loads of Slack chats; these two are my favourites: 1) https://www.youtube.com/watch?v=nlT45ikSEOE&feature=youtu.be&list=PLVi9lDx-4C_Rwb8LUwW4AdjAu-39PHgEE , 2) https://www.youtube.com/watch?v=mT4jJHf929Q&amp%3Bindex=8&amp%3Bt=1578s&amp%3Bab_channel=TonyKay . Until a unified source of Fulcro know-how comes up in the form of new videos or books, learning Fulcro does involve a high upfront investment of time, which I am more than willing to pay, in hope for the long-term benefits. There's so much more to learn and I am just starting to experiment with Fulcro. Look forward to sharing more along the way. P.S. I can watch the videos over and over again, but the sudden loud coughing in a few of the videos may be off-putting to some beginners especially when they are listening intently. This didn't deter me and many others from continuing with the learning, but anyhow, the videos would be literally perfect if the coughing can be edited out. My heartfelt thanks to Tony who is not only an awesome and talented OSS author, but a great and generous teacher!

1👍
tony.kay 2020-12-15T16:55:39.499400Z

Thanks for the feedback Alex. Sorry about the audio. I don’t have the time to do everything I’m doing and post-edit videos…those are literally single-take, barely-planned and lightly-outlined attempts at giving people info as quickly as possible. The older videos talk so much about the APIs (that are now out of date) that I hid them to prevent confusion for new users. I agree with you on the second one. I really need to re-make that with updated terminology. I have not watched the first one since I made it, so don’t even remember what is in it…but if you found it that helpful I will consider re-making it (or relisting it if it is up to date enough). If anyone would like to volunteer to post-processes this kind of stuff, I’d be more than happy for the help…or if you just know of an automatic post-processing (like a compression setting on ffmpeg or something) that will make loud noises better, let me know. I cannot afford to re-record an entire video because of a cough 🙂

Alex Piers 2020-12-16T05:02:48.030700Z

Thanks @tony.kay for replying. Your videos are absolutely helpful and you are a great teacher! A re-make that combines the information of the above two videos with the updated terminology would be excellent. Until then, a re-listing would be really nice, maybe also re-list a few more gems from old times? 🙂 Though not a video expert, I would like to volunteer to post-process your videos including editing out any loud noises, etc. Let me know anytime when you need any video editing. It'd be my great pleasure to help. As for the old videos, there is only one way to edit them without breaking the urls and removing all the views, comments and stats: that is to use the built-in trim function in Youtube Studio. You can find more details here: https://support.google.com/youtube/answer/9057455?hl=en . This is for your reference only. To save your time, I think leaving the old videos as they are and post-processing any new videos going forward is a good plan. Thank you so much again for taking the time to record all these awesome videos and sharing your knowledge and creation with us.

JAtkins 2020-12-15T07:56:19.486200Z

https://roamresearch.com#/app/CommunityFulcro

1👍1❤️
Jakub Holý 2020-12-15T09:28:34.489600Z

At https://roamresearch.com/#/app/CommunityFulcro there is > Add a virtual (fake) attr to address as :sale/account Shouldn't it be "".. to Sale ..."? Also, what is a virtual/fake attribute? One that does not have a field in the db?

JAtkins 2020-12-15T14:46:36.495700Z

Yep on both

1👍
JAtkins 2020-12-15T07:57:47.487900Z

I hope y'all find this useful. I'll be watching the slack chat for anything that catches my eye. Tag me if you want something specific added. If you want to add material yourself let me know and I'll add you as an editor.

JAtkins 2020-12-15T07:58:30.488600Z

If anyone has some ideas of stuff that's already gone off the chat link it and I'll add it as I can.

JAtkins 2020-12-15T07:59:34.488900Z

See this page first: https://roamresearch.com#/app/CommunityFulcro/page/y0-H3KDlM

Jakub Holý 2020-12-15T08:19:14.489200Z

I mean that in my code I have

(defrouter DetailsDisplayRouter [this {:keys [current-state] :as props}]
  {:router-targets [LatestBillRunList SubscriberList]}
  (case current-state
    :pending (dom/p "Loading...")
    :failed (dom/p "Failed")
    (do ;; :initial / nil: no route selected yet, route to the latest bill runs & show nothing in the meantime
      (when props (routing/route-to! this LatestBillRunList (comp/get-computed this)))
      nil)))
as a workaround so that a component can route to its sibling without knowing about its nested routers, but as you say it is side-effecting and wrong

Jakub Holý 2020-12-15T09:28:34.489600Z

At https://roamresearch.com/#/app/CommunityFulcro there is > Add a virtual (fake) attr to address as :sale/account Shouldn't it be "".. to Sale ..."? Also, what is a virtual/fake attribute? One that does not have a field in the db?

Jakub Holý 2020-12-15T09:58:08.495100Z

Update: the proposed solution of using :ui/ready? solved the problem @tony.kay you mentioned that > Attempt to get an ASM path [..] for a state machine that is not in Fulcro state. ASM ID: <some router component> is mostly harmless. To fix, you recommended > You can use app/set-root! with initialize state, then dr/initialize! or dr/change-route!, then app/mount! with NO initialize state to get rid of most or all of those. Basically: Make sure you’ve explicitly routed to a leaf (target) before mounting. I have tried that - in my init fn I have

...

  (app/set-root! app mb-ui/Root {:initialize-state? true})
  (dr/initialize! app)
  (history/install-route-history! app (html5-history))
  (setup-RAD)
  (dr/change-route! app (dr/path-to mb-ui/Intro)) ; overridden in app's on-mount but this makes sure the root router is initialized
  (log/info "App init (almost) dome") ; FIXME rm
  (app/mount! app mb-ui/Root "app" {:initialize-state? false})
however the warning did not go away: > INFO [client:146] - App did mount > DEBUG [com.fulcrologic.rad.routing.html5-history:93] - ["Pushing route" route params] => > WARN [com.fulcrologic.fulcro.ui-state-machines:?] - #error {:message "", :data {}} Attempt to get an ASM path ... ASM ID: :mb.ui/RootRouter > DEBUG [com.fulcrologic.fulcro.ui-state-machines:?] - Trigger :mb.ui/RootRouter So it seems to be a timing issue, the rendering starts right before the router UISM gets started. I suppose the solution is either (1) ignore the warning, it is harmless or (2) add`:ui/ready? false` to the Root and only switch it to true and start rendering anything after the routing system is ready (I guess I could simply (transact! app [(set-ui-ready)]) at the end of init since transactions are executed in order and thus this will run after the UISM start transactions issued by dr/initialize!). Correct? Thank you!

JAtkins 2020-12-15T14:46:36.495700Z

Yep on both

1👍
tony.kay 2020-12-15T16:46:09.497400Z

@holyjak correct. The transactions are queued in the default tx processing, so there can be transient flickerings and warnings unless you block rendering until your init is done. You could also try the sync tx plugin, which runs all optimistic stuff synchronously…but it is considered of alpha quality since I have not used it heavily.

1👍
tony.kay 2020-12-15T16:47:03.497900Z

(though I’ve only seen one reported issue, and I think it is mostly harmless): https://github.com/fulcrologic/fulcro/issues

tony.kay 2020-12-15T16:47:52.498700Z

it’s the only thing “open”…returning false from a remote section causes a problem…I still need to fix that, since in some cases your logic would need to return false there.

tony.kay 2020-12-15T16:48:41.498800Z

yeah, that is about as wrong as you can do something 🙂

1😂
tony.kay 2020-12-15T16:49:52.499Z

remember that defrouter is just a macro wrapping defsc…so you can use all component options there except the ones it uses (query/ident/initial-state)…I don’t think you can make it a hooks component, but you could glom onto componentDidUpdate.

1👍
tony.kay 2020-12-15T16:50:39.499200Z

just read the macro source for that it uses, and you can play with using anything it doesn’t

tony.kay 2020-12-15T16:55:39.499400Z

Thanks for the feedback Alex. Sorry about the audio. I don’t have the time to do everything I’m doing and post-edit videos…those are literally single-take, barely-planned and lightly-outlined attempts at giving people info as quickly as possible. The older videos talk so much about the APIs (that are now out of date) that I hid them to prevent confusion for new users. I agree with you on the second one. I really need to re-make that with updated terminology. I have not watched the first one since I made it, so don’t even remember what is in it…but if you found it that helpful I will consider re-making it (or relisting it if it is up to date enough). If anyone would like to volunteer to post-processes this kind of stuff, I’d be more than happy for the help…or if you just know of an automatic post-processing (like a compression setting on ffmpeg or something) that will make loud noises better, let me know. I cannot afford to re-record an entire video because of a cough 🙂

Jakub Holý 2020-12-15T17:00:22.499700Z

thank you!

tony.kay 2020-12-15T17:06:26.499900Z

another thing to say better in the book 🙂

Björn Ebbinghaus 2020-12-15T17:26:18.002700Z

When making a single load! with :parallel true I get pending... in the network tab in Inspect and I get :com.wsscode.pathom/trace merged into my state. Without :parallel true everything works fine. Any clue whats causing this?

2020-12-15T17:31:43.005400Z

Just seen Rich Hickey's announcement about sponsoring open source devs and I instantly thought of Tony. It turns out that Tony is already in the list of those being sponsored from today on https://github.com/orgs/cognitect/sponsoring

2👏74😻3🎉
Jakub Holý 2020-12-15T17:42:12.008300Z

Is the display of Diffs in the Transaction tab of Fulcro Inspect (latest chrome plugin, Fulcro 3.4) broken? When I click a uism/begin transaction, I have to click buttons to load the states before and after. I expect the diffs to get updated therearfter but they still show nil even though when I expand the before/after state, they do differ (in the :pending-route :path-segment ). Is it a 🐛 ?

tony.kay 2020-12-15T17:52:15.008500Z

News to me 😄

tony.kay 2020-12-15T17:58:51.008700Z

Nice. That’s really cool.

tony.kay 2020-12-15T17:59:41.009500Z

@mroerni could be a bug in inspect reporting from Fulcro itself. Does the load work correctly otherwise? (e.g. just an inspect issue?)

Björn Ebbinghaus 2020-12-15T18:02:37.009900Z

Yes. It works correctly.

wilkerlucio 2020-12-15T18:10:42.016200Z

@tony.kay I'm trying to follow the RAD middleware suggestion you talked about earlier, but I'm not sure what kind of transformation I need to do in the middleware, this is what I tried:

(defn account-id-dance [params]
  (update params ::form/delta
    (fn [delta]
      (mc/map-vals
        (fn [vals]
          (reduce-kv
            (fn [out k v]
              (if (= k :some-custom-entity/account-id)
                (assoc out :account/_reverse_link
                  {:before nil
                   :after  [{:account/id (or (:after v)
                                             (:before v))}]})
                (assoc out k v)))
            {}
            vals))
        delta))))

2✅
wilkerlucio 2020-12-15T18:11:01.016400Z

but the format was a guess in my part, how it should go?

Jakub Holý 2020-12-15T18:12:29.017200Z

FYI I am still running into an issue where the UI shows the (non-default) router target in an uninitialized state while the router believes that it is displaying the default target. I still cannot figure out why. I have RootRouter > OrgRouter > ... > DetailsDisplayRouter > [LatestBillRunList SubscriberList] and URL .../subscribers and I expect to see the SubscriberList RAD report - which I do, but it is empty, even though the DB has the data, because the parent router believes it is displaying the other report. This only happens when I go to the URL in the browser, not when I click myself through the app to the state. So how is it possible that DetailsDisplayRouter believes it is displaying LatestBillRunList while it should, and the UI does, show SubscriberList?! The state of of the DB seems inconsistent when I compare the router and the corresponding UISM:

uism/asm-id DetailsDisplayRouter:
 active-state :routed
 active-timers {}
 local-storage {:path-segment ["subscribers"], :pending-path-segment [], :target [::report/id :SubscriberList]}

dr/id DetailsDisplayRouter:
 current-route LatestBillRunList
☝️ so the router and its UISM have completely different view of the world?!

Jakub Holý 2020-12-15T18:13:24.017300Z

From the Tx log:

:40 SM(DetailsDisplayRouter) :timeout! :event-data {}
:40 SM(DetailsDisplayRouter) :timeout! :event-data {}
:40 SM(RootRouter) :timeout!
:38 SM(SubscriberList) :event/loaded
:38 SM(OrgRouter) :ready!
:38 dr/target-ready {:target [:org-nr "123"]} ; -&gt; could this confuse DR to believe it shows the default view?! 
:37 SM(DetailsDisplayRouter) :ready!
:37 LOAD subscribers
:36 dr/target-ready {:target [:com.fulcrologic.rad.report/id :SubscriberList]}
:34 SM(BEGIN): DetailsDisplayRouter {:path-segment ["subscribers"], :target [:com.fulcrologic.rad.report/id :SubscriberList]}

tony.kay 2020-12-15T18:24:32.017700Z

sorry, lost thread of discussion…did you look at wrap-rewrite-values in RAD? It is an example of making a pluggable mw that can rewrite specific attributes as they are found. The save format is just what form_state.cljc from Fulcro uses.

tony.kay 2020-12-15T18:25:48.018Z

ok, open issue in Fulcro with what happens as best you can describe. Feel free to look through the Fulcro code. Look for uses of ido and ilet…those surround all Inspect reporting. I’m guessing the parallel txn_processing.cljc code is just missing a hook to report the end.

tony.kay 2020-12-15T18:26:36.018200Z

Sounds like a bug. The diffs calculate off of downloaded db revisions, and those are on demand now…must be a bug

tony.kay 2020-12-15T18:28:04.018400Z

right, sounds like a bug in either your code or RAD or DR. If the report doesn’t get a will-enter notification, it won’t start the UISM

currentoor 2020-12-15T18:43:01.018600Z

hey @wilkerlucio can you transact a reverse link in datomic? i thought that was for querying only?

currentoor 2020-12-15T18:44:51.018800Z

the RAD middleware is supposed to update fulcro's form delta, while still making it look like a form delta, then some code will translate it into a datomic transaction

currentoor 2020-12-15T18:45:41.019Z

(defmethod rewrite-value :order/id
     [{user-id :user/id
       firm-id :firm/id} [_ id] v]
     (when (and user-id firm-id)
       (if (tempid/tempid? id)
         (assoc-in v [:entity/firm :after] [:firm/id firm-id])
         v)))

currentoor 2020-12-15T18:46:14.019200Z

that's a simple example

currentoor 2020-12-15T18:46:50.019600Z

that method is defined in com.fulcrologic.rad.middleware.save-middleware

currentoor 2020-12-15T18:46:54.019800Z

does that make sense?

Jakub Holý 2020-12-15T18:47:38.020Z

I believe the report did start its UISM. You can see it did load its data. So all is OK - aside of the confused router

Jakub Holý 2020-12-15T18:49:12.020200Z

And there is even target-ready for the subscribers report. (it is followed by another one, for the ancestor router, no ide why. Perhaps that is messing it up?)

wilkerlucio 2020-12-15T18:55:46.020400Z

kind of, we tried changing the format, but getting this error now:

datomic.impl.Exceptions$IllegalArgumentExceptionInfo: :db.error/not-an-entity Unable to resolve entity: [:my.entity/id {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}] in datom [[:my.entity/id {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}] :my.entity/year 2020]
data: {:entity
                 [:my.entity/id
                  {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}],
       :datom
                 [[:my.entity/id
                   {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}]
                  :my.entity/year
                  2020],
       :db/error :db.error/not-an-entity}
java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: :db.error/not-an-entity Unable to resolve entity: [:my.entity/id {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}] in datom [[:my.entity/id {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}] :my.entity/year 2020]

wilkerlucio 2020-12-15T18:57:08.020600Z

this is what the form delta looks like:

{:com.fulcrologic.rad.form/id        {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"},
 :com.fulcrologic.rad.form/delta     {[:my.domain.entity/id {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}]
                                      {:my.domain.entity/year   {:before 2020, :after 2020},
                                       :my.domain.entity/amount {:before nil, :after 1111M}},



                                      [:account/id {:id #uuid "bd99f8e1-a679-4fe7-a82f-090838077bb8"}]
                                      {:account/base-acres
                                       {:before nil
                                        :after  [[:my.domain.entity/id
                                                  {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}]]}}},
 :com.fulcrologic.rad.form/master-pk :my.domain.entity/id}

wilkerlucio 2020-12-15T18:58:42.021200Z

@tony.kay I think would be interesting ot enable the new Discussions tab for Fulcro repository, what you think? did you got the notificaion?

currentoor 2020-12-15T19:07:29.021300Z

you've got maps where i think you meant to place UUIDs

currentoor 2020-12-15T19:07:31.021500Z

{:com.fulcrologic.rad.form/id        #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3",
 :com.fulcrologic.rad.form/delta     {[:my.domain.entity/id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"]
                                      {:my.domain.entity/year   {:before 2020, :after 2020},
                                       :my.domain.entity/amount {:before nil, :after 1111M}},
                                      [:account/id #uuid "bd99f8e1-a679-4fe7-a82f-090838077bb8"]
                                      {:account/base-acres
                                       {:before nil
                                        :after  [[:my.domain.entity/id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"]]}}},
 :com.fulcrologic.rad.form/master-pk :my.domain.entity/id}

currentoor 2020-12-15T19:07:38.021700Z

^ perhaps that's the delta you wanted?

wilkerlucio 2020-12-15T19:16:30.021900Z

yeah, working now, thanks 🙂

tony.kay 2020-12-15T19:19:51.022600Z

I did not get a notification @wilkerlucio, but it if it persists and allows public interaction, it does sound like a good idea.

tony.kay 2020-12-15T19:19:58.022900Z

the history here is super annoying

wilkerlucio 2020-12-15T19:20:18.023200Z

yeah, I think you can go to the Settings of the repo and enable it

wilkerlucio 2020-12-15T19:21:17.023500Z

@tony.kay like this

tony.kay 2020-12-15T19:23:58.023900Z

enabled: https://github.com/fulcrologic/fulcro/discussions

tony.kay 2020-12-15T19:24:13.024200Z

Thanks for the tip..didn’t know they added that. Let’s see how it goes

1👍
Jakub Holý 2020-12-15T19:38:39.024300Z

should I open an issue...?

wilkerlucio 2020-12-15T19:42:44.025100Z

When using ::form/subforms, how to make the subform items removable?

tony.kay 2020-12-15T21:31:53.026400Z

nah, open a PR if you find a fix. I don’t keep issues around I don’t have time to work on, in general

1👍
tony.kay 2020-12-15T21:31:56.026600Z

and I don’t

Jakub Holý 2020-12-15T21:48:12.026900Z

Thank you, I haven't thought of that!

tony.kay 2020-12-15T22:36:01.028400Z

There are instructions for spining it up in dev mode in Development.md, and there are “LANDMARK” markers at the comm spots. I may look at it if I need it…but I never personally use that feature

1👍
Jakub Holý 2020-12-16T08:20:55.033Z

so what do you do to check state changes over time, to find out which transaction changed a value in an unexpected way?

tony.kay 2020-12-16T14:33:12.045Z

Perhaps it is just experience, or perhaps how I structure code, but I rarely find that useful.

tony.kay 2020-12-16T14:34:29.045200Z

Seeing what ran is always useful, but I generally know what things do, so diff is rarely useful

tony.kay 2020-12-16T14:35:39.045400Z

@wilkerlucio added that feature, and I'm sure it helps some, but not really me

tony.kay 2020-12-15T22:36:09.028700Z

so not high prio for me ATM, sorry

2020-12-15T23:37:18.030200Z

@tony.kay Put up a small PR that fixes a minor bug in fulcro-rad-demo: https://github.com/fulcrologic/fulcro-rad-demo/pull/17. I wasn't sure what branching was appropriate; happy to make any changes that would make things more convenient for you. Thanks for all the work you've put into rad!

tony.kay 2020-12-15T23:48:56.030500Z

cool, thanks!