Fork me on GitHub

@tony.kay do link queries refresh as normal? I tried the following query on the root: {:query [{:all-users (prim/get-query User)} {[:current-user '_] (prim/get-query CurrentUser)}] but :current-user in the props was an empty map. Then I tried {:query [{:all-users (prim/get-query User)} {:current-user (prim/get-query CurrentUser)}] and :current-user got populated properly. Now I wrote this query on the root component so I had no real reason to use link queries, but curious as to why it didn’t work


For completness’s sake, I load the :current-user with a df/load


Also, additional but unrelated question: I just got the error > defsc Root: [current-user] was destructured in props, but does not appear in the :query! In this case it was a genuine mistake on my part; I removed current-user from the query but forgot to remove it from the props destructuring (thanks Fulcro!). However I can easily imagine scenarios where I would want to pass props to a component that do not appear in a query, perhaps in addition to props that appear in a query (i.e. I might have a UserProfile component which takes a user prop, containing data pulled by a query, but also a size prop which I just want to specify when I use the component)


@hmaurer i believe roots should not have link queries like [:current-user '_]


that’s only for non-roots that need a root level property


in the root it should just be :current-user and in children it should be [:current-user '_]


And if you use a lambda for the query, it disables destructuring checks

hmaurer12:01:27 Is this the most sensible way to show a loading indicator for some data? (check :ui/loading-data and whether some prop is nil)


Hmm, with is flickering expected? I just tried it and it first renders my UI with nil props, then switches to loading, and then finally renders my UI with the right data


well, not nil; empty


I assume that’s why “flicker free” is specified as a feature in incubator, but…


Scrap my above question; Fulcro incubator’s loading markers answer it I think.


for mutation joins, is there a way to specify that the return value of a mutation can be one of two things? authenticating a user and the response IMO could be a user’s data or reasons why authentication failed to plop into a form


well, I think nobody tried that, but you can make a union query for it, in theory could work the same, but the server needs to know how to handle it, or you could just ask for all the fields (including error reporting and success field) and then just check the keys in the client side


hmm. is there an idiomatic way that people are handling queries/mutations for e.g. authentication forms?


alternatively I guess I could just do the auth mutation and then do a follow-on read for a user’s data?


follow up reads are fine, what I usually do is define a single attribute to represent an operational error, considering all responses are maps, what I do in case of mutations is that if some error happen, the output map will have a :my-service/error key, so in the UI I can write generic handles that check for this key and consider it an error if its present, success otherwise


pessimistic mutations do that as well, you can use it directly, then you can have your ok-action and error-action to do whatever you need:


wow nice, that actually looks like a super clean solution for this use case


really appreciate the help, gonna take a crack at it


@tony.kay it might be for a dumb reason but I couldn’t get the loading flags to work (from fulcro incubator). It should work with the base df/load, right?


(not just with pessimistic mutations)


it should, yes…it’s about load markers….you MUST include a :load-marker (get-ident this) in load params


I beleive the sample login ui state machine uses it?


y, but ooops…that doesn’t use it…probably a diff ws


so there is a demo


ah, I’ll check that right away, thanks


also, again might be a dumb question but if I wanted to use those load markers on the root component, I would need an ident on it?


make a root placeholder


i.e. make a root that does nothing, and put your real root (with an ident) under than


Fulcro app roots cannot have idents


@tony.kay Thanks, that makes sense. I did this but for some reason I am not getting the data in props. The relevant code is:

(defsc RealRoot [this {:keys [all-users current-user] :as props}]
  {:query         [{:all-users (prim/get-query User)} {:current-user [:user/email]} :ui/loading-data]
   :initial-state (fn [params] {:all-users [] :top-bar (prim/get-initial-state TopBar {})})
   :ident (fn [] [:screen :root])}

(defsc Root [this props]
     {:query [{:>/root (prim/get-query RealRoot)}]
      :initial-state (fn [params] {:>/root (prim/get-initial-state RealRoot {})})}
     (div (str props)))
Which prints {:>/root {}}. However my database contains the data:


read more carefully


“component local state”, not props…the example shows it clearly…and the docs spell it out


right yes, I read that, but in this example I was just trying to get some data to my component, not the loading indicator


oh, don’t use a placeholder node


just use a regular key..and don’t load against root


ah, ok. Why? (not load against root)


you’re loading RealRoot now, not Root


if you want to use ff support, it needs an ident


for the marker identity


just get root out of the equation altogether, and you’ll be fine. But I would not use placeholder node syntax for it.


I tried what you suggested (if I understood it correctly) but couldn’t get the placeholder out of root (it didn’t seem to query the right data otherwise). Anyway, even with the placeholder the issue seems to be that the loading indicator (in the state) is never set to true; it’s nil initially then transitions to false. Could you take a quick look please? I copied the code to a gist; it’s short:


I think the problem might be that in your example you use componentDidUpdate, but in my case I want to show the loading indicator as soon as the component mounts, so I would need to initialise the local state of the loading indicator


Alright, after more looking into the docs perhaps I am misunderstanding what is going on. From the doc, I read that :started-callback fires after the application’s initial mount to the DOM. Which means that at that point I would want :loading-visible? in my component’s local state to be true, and so until I’ve finished loading the appropriate data in the :started-callback. But maybe I am going about this wrong? Perhaps I should set a flag in the database that indicates that the basic application data / route data has been loaded, and display an application loading indicator until that flag is true?


Alright, thanks 🙂 I’ll try that then.


having a strange thing happening when attempting to implement the router from the guide. Those other :ui/* fields are coming from initial-state on the LoginPage that the router points to as the default route. If I update those fields on the LoginPage component, they correctly save in its ident location at [:PAGE/login 1] but the LoginPage doesn't see them because it's pulling its props from [:router :fulcro.client.routing/current-route] ??

(defsc LoginPage [this {:keys [db/id router/page server-down] :as props}]
  {:ident         (fn [] [page id])
   :query         [:db/id :router/page :ui/username :ui/password :ui/error [:current-user '_] [:server-down '_] [:ui/loading-data '_]]
   :initial-state {:db/id       1 :router/page :PAGE/login
                   :ui/username "" :ui/password "" :server-down "maybe ..." :ui/error nil}} ;;;)

(defsc-router RootRouter [this {:keys [router/page db/id]}]
  {:router-id      :root/router
   :ident          (fn [] [page id]) ; props are destructured in the context of the route TARGET
   :default-route  LoginPage
   :router-targets {:PAGE/login LoginPage
                    :PAGE/entry EntryPage}} ;;;)
(def root-router (prim/factory RootRouter))

(defsc Root [this {:keys [router] :as props}]
  {:query         (fn [] [:router (om/get-query RootRouter)])
   :initial-state (fn [props] {:router (om/get-initial-state RootRouter {})})}
    (root-router router)))