Fork me on GitHub
#fulcro
<
2017-10-17
>
tony.kay16:10:21

The main problem with load markers in the state tree is that there is that they can be to-many. This creates a problem. The load marker is to-one. So, say you have an element in your UI that already exists: say a list of people. You issue a new load for people. Where does the load marker go?

tony.kay16:10:14

metadata on the vector didn’t work, which is why it is the way it is. Now, if we go with another location in the component (say you query for :ui/is-loading?) will that work in all cases?

tony.kay16:10:19

Query: [:a {:j [:loading? :x]}]
Graph: {:a {:j {:x 1}}}
Result: Works. Can toggle the loading flag on

Query: Same
Graph: {:a {:j [{:x 1} {:x 2}]}}
Result: No go. Cannot place loading marker because target isn't a map, it's a vector

tony.kay16:10:44

Now, from a graph perspective, root is always singular, so starting from root, we have a node on which we can always place marker data. Some possibly solutions (not backward compatible): 1. Put all load markers just on the root node in a map keyed by target path (or perhaps an invented “load label” (e.g. (load this Boo {:marker :my-marker}) and query for [:fulcro/load-markers '_] and pull :my-marker from it whereever you need it). 2. It is true that targeted loads should have a parent that already exists. Thus, the target path (which can contain numbers to target an element of a to-many list) should always be a field of an existing node that is represented as a single thing (a map). Thus, we could (I think) reliably place the load marker on the parent of the target field. E.g. a target path of [:thing 3 :comments] would place the load marker at [:thing 3 :ui/loading?]. Given that the parent is responsible for the rendering of the load marker, this seems to make sense. Ah, but loads can be to an ident (`(load this [:thing 3] Thing)`). In that case the current scheme works (it replaces the node with a load marker), but there is no definitive “parent”.

tony.kay16:10:49

As I think about this, I’m really attracted to option 1. It decouples load markers from touching your state at all. And gives you an explicit query mechanism to get the data you need (if you want it).

tony.kay16:10:38

It does require that the component pulling the load marker have something in it’s state, since the internal query engine doesn’t allow a query that only contains link query data with no node for the component itself in the graph.

tony.kay16:10:03

but that should always be the case, since you’re going to show the load marker from something that is the parent of the thing being loaded (which means that component will have a join for the child being loaded).

tony.kay16:10:42

3. Same as (1), but put the load markers in a table, with the marker name as the key. Then the query becomes [:prop-of-parent [:fulcro/load-markers :my-marker] :other-props], and the destructuring can just be (let [{:keys [my-marker]} (om/props)] ...)

tony.kay16:10:58

Hm…this is getting nicer. Now we can do a defui for the LoadMarker, supply a query (and ident) function…perhaps even use a multi-method in render with a default. Now you have an easy way to customize the rendering of the marker. The query becomes [:prop-of-parent {[:fulcro/load-markers :my-marker] (om/get-query fulcro/LoadMarker)} :other-props] and you get a factory like ui-load-marker,

tony.kay16:10:27

That sorta sounds like how someone should have designed it from the beginning 😕

tony.kay16:10:28

We should complain to management 😉

fatihict18:10:33

#3 sounds great