Fork me on GitHub
#fulcro
<
2020-03-26
>
tony.kay01:03:36

Version 3.1.1 of Websockets: We changed it so that it connects automatically by default and can be told to delay start until I/O as an option. The option is useful in things like devcards and workspaces where a bunch of apps might start all at once, and overwhelm connection limits.

tony.kay01:03:02

version 3.1.0 had made delay start the default, which caused a number of ppl some issues.

holyjak13:03:35

How do I make a picker? When a user arrives to my app, I want to ask him to select a target organization; once selected, I would store it to :ui/selected-org-number in the DB and use it to filter various reports etc. I want to have an autocomplete for the option. So I have followed the timezone id example from the demo and ended up with this

(form/defsc-form OrgPickerForm [this props]
  {::form/id                  kostnadsdeling/organization-number
   ::form/attributes          [kostnadsdeling/organization-number]
   ::form/cancel-route        ["landing-page"]
   ::form/route-prefix        "org-picker"
   ::form/title               "Select an org"})
which works but 1) once selected, how do I store the selected value? 2) currently this logs an error about a uism for the form not being started; I have tried to fix it with (uism/begin! app form/form-machine [:component/id :OrgPickerForm] {:actor/form mb-ui/OrgPickerForm}) , similarly to the fix for reports, but it does not work (The value given for actor :actor/form had (or was) an invalid ident) Thank you!

tony.kay14:03:32

@holyjak RAD is meant to be used with routing. It self-starts the state machines as you route to the thing. In this case you’re not trying to create OR edit a pre-editing server-side thing, so that isn’t a report OR form…it’s just hand-built UI you need to build.

tony.kay14:03:28

I’ve got ideas around making generated flows/wizards/etc more automated, but you’re a very early user 🙂

tony.kay14:03:36

One idea I had this morning is to let you associate your own state machine definition with a component (form or report). For the use-case you’re describing, you’d be using all transient attributes and perhaps some well-defined ID that you’d pre-populate in the client. Then there’d be a way for you to control the fact that no I/O is needed for the form…but I ddon’t have local-only support written yet

holyjak15:03:09

I forgot to mention that I'm really impressed by RAD :) My use case is a dashboard-like page with some reports displayed by default, some showing on demand (typically master-detail),some inputs to narrow down the data.

tony.kay15:03:33

I’m going to add some kind of “master report” concept, where you can concentrate all of the controls into the master, and have it control the child reports. That way you could have a table, chart, etc all embedded in one container, and have them update based on what that outer container does.

tony.kay15:03:57

probably will make that concept also support embedded forms, and also allow the container to do things like sub-routing. Imagine a container that controls (via a state machine you add) which thing is showing, and what its parameters are. Easy to then make many many things (checkout flows, dashboards, wizards, UI tutorials, etc.)

tvaughan15:03:40

I'm having a problem setting up a form. I think I have everything setup correctly according to the book and videos, yet I'm getting the errors Query ID received no class (if you see this warning, it probably means metadata was lost on your query) #error {:message "", :data {}} followed by Failure dispatching optimistic action for AST node. What I have looks like:

(defmutation set-form-state*
  [{:keys [:form/class :form/ident]}]
  (action [{:keys [state]}]
          (swap! state (form-state/add-form-config* state class ident))))

(defsc TeamForm
  [this {:keys [team/id team/name team/members] :as props}]
  {:query [:team/id :team/name {:team/members (get-query PersonForm)} form-state/form-config-join]
   :ident :team/id
   :route-segment ["team" :team/id]
   :initial-state {}
   :will-enter (fn [app {:keys [team/id] :as route-params}]
                 (let [ident [:team/id (uuid id)]]
                   (route-deferred ident #(load! app ident TeamForm {:post-mutation `target-ready :post-mutation-params {:target ident}}))))
   :form-fields #{:team/name}
   :componentDidMount (fn [this] (transact! this `[(set-form-state* {:form/class TeamForm :form/ident ~(get-ident this)})]))}
  (dom/div :.ui.two.column.relaxed.grid
           (dom/div :.column
                    (dom/h1 :.ui.dividing.header
                            "Edit Team")
                    (dom/form :.ui.form
                              (dom/div :.field
                                       (dom/label
                                        "Team Name")
                                       (dom/input {:name :team-name :type :text :defaultValue name}))
                              (dom/div :.ui.relaxed.list
                                       (map ui-person-form members))
                              (dom/button :.ui.positive.button {:type :submit}
                                          "Update")
                              (dom/button :.ui.button
                                          {:type :button :onClick #(transact! this `[(form-state/reset-form!)])}
                                          "Undo Changes")))))
It's the componentDidMount that's triggering the error. Where have I gone wrong?

tony.kay16:03:23

You’re too late (and the * suffix is meant for functions of state map, not mutations themselves). See book and Pre Merge

tvaughan16:03:33

Got it. Thanks. I tried pre-merge but that didn't work either. No error, nothing happened. Found an example elsewhere that used componentDidMount. Will go back to pre-merge. Thanks again

tony.kay16:03:44

you could also put it in a post-mutation of the load itself

holyjak21:03:40

Hi! In the RAD demo, Inspect - Index Explorer fails to load the indices. I have tried to fix it by adding an index-explorer as described at https://wilkerlucio.github.io/pathom/#_setting_up_the_index_explorer_resolver and adding it to the list of resolvers in com.example.components.parser/parser (and (restart) ) but it still does not work. Why?

holyjak21:03:23

Update: Fixed, my query is wrong, it should have asked for :organization/latest-invoice . Q2: How do you troubleshoot when a query does not return the expected data and the resolver seems not to be called (according to a println in it not printing anything)? I am running

[{[:organization/organization-number "985061556X"]
  [{:latest-invoice [:invoice/id]}]}] 
and have this resolver
(pc/defresolver latest-invoice [env {:organization/keys [organization-number]}]
     {::pc/input  #{:organization/organization-number}
      ::pc/output [{:organization/latest-invoice [:invoice/id]}]}
     (println "Q latest-invoice for" organization-number) ;; does not appear in the server REPL
     {:organization/latest-invoice (queries/get-latest-invoice env organization-number)})
I am quite sure the resolver is correctly added to the parser's list of resolvers. I get this response
{[:organization/organization-number "985061556X"]
 {:latest-invoice {}}}
and the server REPL prints > io.undertow.request:- 97 - Matched default handler path /api but the println in the resolver is not triggered. How do I troubleshoot this? Thank you!!!

holyjak21:03:23

Update: Fixed, my query is wrong, it should have asked for :organization/latest-invoice . Q2: How do you troubleshoot when a query does not return the expected data and the resolver seems not to be called (according to a println in it not printing anything)? I am running

[{[:organization/organization-number "985061556X"]
  [{:latest-invoice [:invoice/id]}]}] 
and have this resolver
(pc/defresolver latest-invoice [env {:organization/keys [organization-number]}]
     {::pc/input  #{:organization/organization-number}
      ::pc/output [{:organization/latest-invoice [:invoice/id]}]}
     (println "Q latest-invoice for" organization-number) ;; does not appear in the server REPL
     {:organization/latest-invoice (queries/get-latest-invoice env organization-number)})
I am quite sure the resolver is correctly added to the parser's list of resolvers. I get this response
{[:organization/organization-number "985061556X"]
 {:latest-invoice {}}}
and the server REPL prints > io.undertow.request:- 97 - Matched default handler path /api but the println in the resolver is not triggered. How do I troubleshoot this? Thank you!!!

codonnell21:03:30

Is the tem-organization namespace a typo?

holyjak22:03:15

Yes. Fixed now.

codonnell22:03:37

Just a slack typo, then? For debugging, one thing you could do is look at the pathom indexes to make sure these attributes are connected as they should be.

holyjak22:03:05

Yes. See my previous question - indexes don't work for me in the Inspect

tony.kay23:03:50

Indexes are loading fine for me in Inspect using demo

tony.kay23:03:58

try reinstalling Inspect?

codonnell23:03:36

Looks like maybe your problem was solved in #pathom? It's possible to see the indexes from the server-side; you don't need the index explorer. They should be accessible in env under ::pc/indexes in any resolver, or you could write a parser plugin to print them if you prefer.

holyjak09:03:27

@ Do you mean that indexes work for you out of the box, without manually adding the index resolver? I know that the Index Explorer worked for me on another project. Can I try manually what it does, i..e send a query via Inspect - Query?

holyjak10:03:09

Ok, I noticed in Inspect - Network that it lists the index query and got 500 server error back, and the server logs this Transit error: > Not supported: class com.fulcrologic.rad.blob$blob_resolvers$fn__25566 When I commented it out, it failed on my own resolver: > Not supported: class my.model$all_organizations_search__41722 How to fix?

tony.kay16:03:50

Are you not using the pre-written parser from the RAD lib???

tony.kay16:03:30

it sounds like somehow you’re putting the resolver functions into something that is being transmitted, and ti is telling you that it cannot serialize a function. Or perhaps I have a bug somewhere that is doing that, but it isn’t misbehaving for me.

holyjak16:03:42

I am using the pre-written parser (from sql). I will switch to the latest master and try again.

tony.kay16:03:50

oh…the Datomic one is the one that I use all the time…make sure they match

tony.kay16:03:09

I may have refactored something and forgot to touch that…the problem with a multifaceted demo

holyjak17:03:13

Hm, I should have though of this myself, I know you use primarily Datomic.

tony.kay17:03:05

Yes, definitely consider the SQL side a “hopeful promise if someone is generous enough to refine it into production quality”. The Datomic side is what you should be playing with for now.

tony.kay17:03:00

That said I just started it up and noticed: 1. The indexes worked fine. 2. Saves of enumerated values are broken 3. The autocomplete control isn’t display a label…prob broken on both sides since that isn’t a db thing

tony.kay17:03:50

One of my goals is to get some Cypress tests written that can run through every aspect of the demo so I can quickly check everything for regressions…but until I get the demo fleshed out into something that looks like a real app instead of a bucket of random crap I don’t want to write those.