Clojurians
# om

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

nano 00:02:42

Anyone have any examples on how to prevent figwheel from resetting the state of the app. I tried declaring (defonce app-state (atom ...)), but that doesn't seem to be enough.

dnolen 00:03:13

@nano you may also need to (defui ^:once Foo …)

dnolen 00:03:38

otherwise new classes will be instantiated and React will re-mount everything

nano 00:04:44

ah, hoping to continue developing straight on the TV now that I have the basic UI working. As I can do arbitrary cross site XhrIo requests, I'm hoping the ws:// figwheel channel will work fine as well.

noonian 00:09:35

also need defonce on the reconciler I think

nano 00:11:32

defonce'd app-state and reconciler, and added ^:once to all defui's, when saving, all content disappears, even if the query remains the same. any suggestions?

anmonteiro 00:16:34

@dnolen: not sure if any of this helps

anmonteiro 00:17:22

Because of add-root!, the class will be instantiated anyways

anmonteiro 00:17:28

even with defui ^:once

anmonteiro 00:18:15

I've managed to get the app-state to be maintained on reload, but never component local state. Is this expected?

nano 00:18:57

component local state = routing via queries for example?

nano 00:19:11

or explicit set-state?

anmonteiro 00:19:19

explicit local state

anmonteiro 00:19:37

@nano: are you using routing with Html history?

anmonteiro 00:19:49

if you are, that's a whole other problem :simple_smile:

nano 00:20:19

No, I should add history at some point. But right now I just replace the :child part of my top query that loads the child components.

nano 00:21:14

As this isn't a browser application having the traditional history doesn't make much sense, but need to keep track of the navigation stack later on.

anmonteiro 00:21:26

Right, no other ideas then; I'm reporting based on my experiments with adding Om Next reload behavior functionality to devcards

anmonteiro 00:22:37

but haven't tested with dynamically changing queries and such

nano 00:55:09

Humm.. I think it might be the initial IQuery that's popping back, which defaults to my root.

nano 00:55:39

@nano uploaded a file: Untitled

nano 00:56:48

So in the above snippet, session/route and session/params are still correct, but if I do (om/get-query (om/class->any reconciler App)) after the reload, the child points to :categories, instead of the target pointed out by :session/route (#object [cljs.core.Atom {:val {:session/route :category, :session/params { ....)

andrewboltachev 05:11:21

Sorry, repeating question:
@dnolen: @anmonteiro : Here, in 2nd sinppet https://github.com/omcljs/om/wiki/Components%2C-Identity-&-Normalization#adding-reads are '[:name :points] just for documentation purposes? I mean in this particular case. For me it seems that it isn't ever passed to read-fn, and get-people is doing all the job for deciding on whatever fields would be passed to Person component.

Would read-fns in the future accept trees (say, {:list-one [:name :points]}) as a key, instead of single keys, or is that wrong thinking?

dnolen 05:13:24

@andrewboltachev: just write your own parse function if you need your own behavior

dnolen 05:13:38

there’s nothing about the defaults that say you need to be constrained by them

dnolen 05:14:05

parse is a function of a specific signature and behavior, anyone can write something that satisfies it

andrewboltachev 05:19:28

@dnolen: I know you said in one talk that there might be different types of clients, e.g. mobile just needs :name and :price, and desktop one :description also. I started to think that these query parts will do exactly this, i.e. fetch needed fields (with arbitrary level of nesting). If I can't get this working now so probably I'm missing something.

But thanks, I'll try to write parse fn (and other stuff, if necessary) which does exactly this

nblumoe 16:18:16

Is it possible to get lookup refs to associated data resolved, simply with the correct query alone? Or do I need to manually wire this up in a read function? I can get it to work with something like (query [this] [{[:users/by-id 10] [:user/name]]) But instead of a hardcoded id 10 I would need to retrieve the id from the component's props

nblumoe 16:20:58

trying to use (om/props this) in either the Query directly or via QueryParams breaks the component ;(

dnolen 16:25:15

query needs to work without instantiating the component so you can’t do that

dnolen 16:25:31

you could invoke set-query! on the component when it mounts

nblumoe 16:29:57

thanks. any opinion about whether to do this or merge the associated entity data in the according read function instead?

stuarthinson 16:42:12

@anmonteiro working on my first om next app with aemette - should my remote parser’s read be aware of dom-com/props? if not, any tips on writing the read in clojurescript such that only the contents of dom-com/props are requested from the remote?

stuarthinson 16:42:44

also, thanks for putting together the template and blog posts!

anmonteiro 16:45:46

@stuarthinson: the remote parser should not be aware of dom-com/props; this is a made-up thing to hold the query for the current route. What actually matters is parsing whatever is inside it

anmonteiro 16:46:30

here's an example:
``` (defn recurse-remote [{:keys [parser target query state ast] :as env}] (let [v (parser env query target)] (if (or (empty? v) (nil? target)) {:value v} {target (update ast assoc :query v)})))

(defmethod read :dom-com/props [{:keys [parser query ast target] :as env} k params] (recurse-remote env)) ```

anmonteiro 16:47:05

(the :dom-com/props read method always uses recursive parsing to get whatever it needs)

stuarthinson 16:47:26

makes sense, thanks! i’ll give it a try

stuarthinson 17:36:10

@anmonteiro thanks! i needed to tweak recurse-remote to (defn recurse-remote [{:keys [parser target query state ast] :as env}] (let [v (parser env query target)] (if (or (empty? v) (nil? target)) {:value v} {target (om/query->ast v)}))) is that an indication that the read corresponding to the component’s query has a problem?

anmonteiro 17:46:18

@stuarthinson: not sure what you mean by the read method having a problem?

dnolen 19:55:21

@nblumoe: your approach just seems a bit backwards to me

dnolen 19:55:42

obviously the parent component has the ident if you’re going to pass it as props

dnolen 19:56:07

so I don’t really see why the child component needs it at all in this case

nblumoe 20:37:59

@dnolen so, the child component should have the "foreign key" in its query and the parent component would use that on rendering to inject the relevant foreign attributes into the child components props?

dnolen 20:41:28

@nblumoe: no

dnolen 20:41:41

construct your queries like all the example show

dnolen 20:42:03

the join key is in the parent, the query is provided by the child

dnolen 20:42:07

in this case the join key is an ident

nblumoe 20:43:08

Whereas the ident cannot specify an ID then, at least not in the static methods

dnolen 20:44:50

right that doesn’t change at all

dnolen 20:44:57

just talking about overall approach

nblumoe 20:45:44

Oh yeah, that's fine and I think I have the proper understanding of why this has to be like that in the static methods, thanks.

nblumoe 20:46:56

Nevertheless, there is the need to resolve a specific foreign entity and I can see at least the two approaches of doing it from the reader or via runtime query modifications

nblumoe 20:48:09

Ideally I would image this to have a simple declarative way of expressing it and I don't see that yet.

nblumoe 20:48:42

Something is missing for me to get this I guess

dnolen 20:49:20

you can probably do this with an inline link

nblumoe 20:49:39

With my current understanding, I could use functions, wrappers or macros to achieve it, but this seems very cumbersome for such a common need

dnolen 20:49:46

and avoid reading stuff (which doesn’t sound like a good idea to me), and setting the query at runtime

dnolen 20:50:05

@nblumoe: none of those approaches seem desirable or necessary

dnolen 20:50:31

read the Thinking With Links tutorial and see if you can see how it can be done

nblumoe 20:52:02

Will have a look again. But I am afraid I read this often enough already (too often? ;), also the other resources. And it does not have an example for a dynamic link, but only a simple root attribute (which was easy to get working)

dnolen 20:54:15

what I’m suggesting is that maybe it should work and you should try it

dnolen 20:54:28

if it doesn’t work then maybe we should make it work

dnolen 20:54:49

which is to say, I don’t have an answer but maybe you can help figure out what it should be

nblumoe 20:55:15

set-query! worked out course, but I found it less than ideal having to define the query twice (yes, can be dry with another function/var) and also to retrieve that data from the props then without having to reshape it beforehand upstream (e.g. in reader or parent component)

dnolen 20:55:25

{[:current-user _] …}

dnolen 20:55:50

where that resolves to yet another link, which itself will get resolved

dnolen 20:56:00

then you don’t need to bother with all this extra stuff

dnolen 20:56:54

@nblumoe: right, though I’m not really concerned about perceived modeling issues with set-query!

dnolen 20:57:04

it works how it works and I’m not interested in changing it

dnolen 20:57:43

it may not be the ideal solution for your specific case, but that’s just another concern

nblumoe 20:58:06

Hm, but there is no single for state I could resolve to. Of course I have users/by-id but obviously this needs an ID to resolve it. And I want to show multiple associated entities on a single page...

dnolen 20:58:34

but the id must come from somewhere

nblumoe 20:58:38

OK, thanks again. I just thought I might have been missing something, but apparently not.

dnolen 20:58:46

if this happens after view presentation, then you should be perfectly fine with set-query!

dnolen 20:59:26

if the id can be supplied before view presentation then what I suggested could be a reasonable alternative

nblumoe 20:59:31

Yes, the ID is an attribute of entity A pointing to an entity B, simple foreign key

dnolen 20:59:45

this part is not relevant for the discussion we’re having

dnolen 20:59:56

only the two points I said above

dnolen 21:00:12

either A) you have the data before your view renders or B) you don’t

nblumoe 21:00:13

Just said, WHERE the ID come from

dnolen 21:00:22

that’s not what I’m talking about

dnolen 21:00:43

for the B) case you need set-query!, for A) you could do something else like I’ve already suggested

nblumoe 21:01:21

Ah okay, gotcha!

nblumoe 21:01:55

Will play around with the options for A)

nblumoe 21:03:10

because I found it not very elegant having to put it into componentDidMount when actually not needed to rely on the component lifecycle

nblumoe 21:27:27

Thanks for taking the time, David! :+1:

hugod 21:40:48

In a list with a component for each item in the list, deleting an element from the list causes reconcile! to look at the item’s row component, and try to calculate new props for it. Unfortunately, the query it uses for this is the component’s local query rather than the full query. The row component has an ident, but it doesn’t seem to be used to calculate the result from full-query. It has a parent set, but path returns nil on the component. I’m at a loss to see what to change so that the reconcile! uses the correct query. Should it have a path set? Why isn’t the ident being used?

dnolen 21:44:26

@hugod: too little and too much information here - some minimal case would be useful.

hugod 21:46:36

@dnolen: ok, I’ll try and extract something - this is with React Native if it makes a difference. It seems I don't understand the logic around how full-query works.

dnolen 21:48:31

the query for any component’s data must be the full query for that component to the root

dnolen 21:48:51

full-query is the entire query that leads to that component with the other stuff elided

dnolen 21:49:39

it has to work that way for the obvious reason that child queries are contextless

dnolen 21:49:47

they don’t mean anything without the parent query

hugod 21:51:36

Right, that is the theory, but it seems to be using an unrooted query in this case, and I’m not sure which mechanism for going back to the root is not working.

hugod 21:52:52

It seems it could do it through parent or ident or path

dnolen 21:55:56

right this just grabbing at straws

dnolen 21:56:06

it could be bug in your code or in Om

dnolen 21:56:10

need a minimal case

jlongster 22:04:44

I'm using (om/factory Component {:keyfn :id}) and id is definitely a proper id, but it doesn't look like the component is getting a key property (looked at the component tree with React devtools). anyone else seen this?

jlongster 22:05:22

it's probably my fault

jlongster 22:05:47

oh, nm yep it's my fault.