Fork me on GitHub
#om
<
2015-10-30
>
steveb8n00:10:23

when I switch from om.dom to sablano everything works until I remove the om.dom require from the namespace. Then I get Uncaught ReferenceError: ReactDOM is not defined

steveb8n00:10:56

has anyone else seen this? the workaround is simple i.e. don’t remove the unused om.dom require

steveb8n01:10:16

happy to log an issue if it not ignorance on my part

minimal01:10:52

reactdom is from react 0.14, sablono is on 0.13, latest om alphas bring in react 0.14

steveb8n01:10:18

I already have 0.14 (only) in my deps tree. I see what you mean about sablano using 0.13. I think you mean add another require to my ns to pull in 0.14

steveb8n01:10:56

if that’s the case then I might as well leave om.dom in there for now since that works well (until sablano updates)

joshfrench01:10:21

sablono 0.3.7-SNAPSHOT has the updated dep

steveb8n01:10:40

perfect, thanks. I’ll try that

steveb8n01:10:47

but I can wait till a 0.3.8 release

jannis02:10:14

Ha, this was fun. How about a really, really, really crappy drum machine built with Om Next? http://jannis.github.io/om-next-drum-machine/ 😉

thosmos06:10:37

@steveb8n: I've got [cljsjs/react "0.14.0-1"] [sablono "0.3.6" :exclusions [cljsjs/react]] in my deps and it seems to be working ok

thosmos06:10:09

and no reference to om.dom in my ns

steveb8n06:10:58

@thosmos didn't think of that. Thx

dvcrn07:10:16

hm anyone else having problems with willReceiveProps? Sometimes it's getting called, most of the times not

dvcrn07:10:31

I'm now abusing render for my willReceiveProps code because it's consistently getting called whenever state updates

dot_treo07:10:03

does willReceiveProps make even sense with stateless components?

dot_treo07:10:51

When using react directly I only ever use it to fix some problematic behavior in a stateful component

dvcrn08:10:04

in any way, even if I do it without willReceiveProps, I still have odd behaviour. example: I am working on a editor. On every keypress I update the state with transact!. - I'm trying to change a state key from outside with swap! - render triggers successfully on my component - (om/props this) does not include the updated state field. Even consequent swaps is not changing that - as soon as I do a keypress and transact! triggers, the component suddenly receives the changed key that I just swapped from outside

dvcrn08:10:40

how come render triggers but without my prop if I update the state with swap!?

dvcrn09:10:04

ok so I got curious about this and tried to dispatch the transaction from my root component. - created a async channel inside didMount - on outside events, put the entire callback into the channel like so:

(go (>! root-channel #(om/transact! % `[(app/my-super-cool-mutation)])))
- go-loop inside didMount checks for these and executes the fn with this parameters. this is hacky as hell but gets around the problem. Now the render components receives the correct parameters right away am I doing something wrong with my swap!?

jannis11:10:30

@dvcrn How were you using swap! outside the component? With om/transact!? If so, you'll have to pass the keys to reread to the call like so (om/transact! reconciler '[(app/my-mutation ...) :app/some-key])

jannis11:10:42

Only then will the component that queries :some/key receive its new value via new props.

jannis11:10:20

If the component initiates the transaction, that happens automatically.

dvcrn11:10:21

@jannis: with the latest alpha that's not possible anymore. transact is only for components that have queries

dvcrn11:10:00

I used a normal swap but now my core.async hack

jannis11:10:54

@dvcrn Looking at the code transact! still works when called with the reconciler.

dnolen11:10:05

@dvcrn: that’s not quite true, you can use the reconciler

dnolen11:10:50

@dvcrn: you using a form input of some kind? If you are you have to be more careful.

dnolen11:10:19

(nothing has changed about how form inputs work between Om Now & Next)

dnolen11:10:32

@dvcrn: I’m not sure about the future of willReceiveProps we may just not support it - it exists to solve a React problem we don’t care about.

maoran11:10:36

is it me or ? - I can't get the Components, Identity & Normalization example to work with 1.0.0-alpha12 -- "ListB" items are not updating (works fine till -alpha11)...

dnolen11:10:35

@maoran: ok I see the bug, will fix and cut a release

dnolen12:10:07

@maoran: should be fixed

maoran12:10:01

yes! confirmed

jannis12:10:47

@dnolen: What do you think about allowing (om/get-computed this) (where this is a component) as a shortcut for (om/get-computed (om/props this))?

dnolen12:10:11

I’m ok with that

dnolen12:10:16

file an issue please

jannis12:10:23

Cool, will do!

jannis12:10:11

It works nicely though, I used it last night. I like the separation of query results and extra stuff.

jannis12:10:29

Thanks for all this simple_smile

dnolen12:10:31

np! Thanks for all the feedback simple_smile

dnolen12:10:52

so thinking that we’ll just copy the syntax for recursive queries from Datomic Pull

dnolen12:10:01

it’s of course also possible that components can be recursive w/o explicit recursion in the query like this - i.e. the recursion exists only in the component graph.

Lambda/Sierra14:10:06

I've seen from the Datomic mailing list that there are recursive patterns which the Pull syntax can't represent.

Lambda/Sierra14:10:25

E.g. when you have to step through more than one attribute to get to the recursive case.

dnolen14:10:40

@stuartsierra: right that’s what I mean by the recursion being present in the components themselves

dnolen14:10:43

@jannis not excited about adding things to om.dom

jannis14:10:03

@dnolen: No problem. I was just wondering. React had something similar with classSet but they moved it into a community project (https://github.com/JedWatson/classnames). I find it almost too small to justify its own repository. 😉

jannis14:10:38

Then again, it's small enough to define again and again in every project.

drcode15:10:06

Is it kosher to return singleton results in parsing functions, ala having a read function return {:value {:foo 22 :bar 33}} ?

drcode15:10:25

It seems to work, but I'm not sure if I'm asking for trouble...

drcode15:10:05

i.e. as opposed to returning {:value [{:foo 22 :bar 33}]}

drcode15:10:10

Never mind, I can see this is done in the examples

drcode15:10:19

Should have checked those first

dvcrn15:10:31

@dnolen: not a form field, no. It's an editor. When a file is being loaded or saved, the backend sends a ipc message to the frontend (om). The receiver part is then calling transact!. I tried the transact! on the reconciler but got the "you can only use it if your component implements queries" error message

joshfrench15:10:25

the query union syntax isn’t something Datomic understands natively, right? i’ll have to massage that in my parser?

joshfrench15:10:03

i tried running the query generated by the tutorial:

IllegalArgumentExceptionInfo :db.error/invalid-recur-limit Cannot interpret as a recursive pull specification: {:dashboard/post [:id :type :title :author :content :favorites], :dashboard/photo [:id :type :title :image :caption :favorites], :dashboard/graphic [:id :type :title :image :favorites]}  datomic.error/arg (error.clj:57)

dnolen15:10:17

@dvcrn: ah that’s just a bug

dnolen15:10:02

@dvcrn: hrm no I don’t think so, looking at the code of transact that should work

dnolen15:10:08

seems like you did not actually pass a reconciler

dvcrn15:10:22

errr.... let me check again

dnolen15:10:37

@dvcrn: look at the code for transact!

dnolen15:10:45

if it gets a reconciler skips validation

dnolen16:10:31

@drcode: yes that’s allowed, nothing requiring joins to be one-to-many many-to-many

dnolen16:10:55

@joshfrench: not supported by Datomic

dnolen16:10:15

you will want to write your query and then use the different pull selectors depending on what you have in hand

dnolen16:10:56

@bbss: we should try to paste things like that simple_smile

bbss16:10:43

I wanted to make a snippet but it didn't suggest that on enter like it normally does. Oops!

flipmokid16:10:32

Hi all, I'm playing around with om next. I want to have a page showing a list and a detail pane. I call my service at the beginning for the list which just contains the very basic data (say ids and descriptions). When the user clicks on an item I want to go off to the server and get the additional data (say id and body). I had originally thought that the list and the detail components could use the same data list, just with the detail component having a query param based on the id of the document it wants together with the extra properties it wants to display. Does this make sense? If so can anyone help me with what the queries should look like?

joshfrench16:10:30

@dnolen: got it. thanks!

dvcrn16:10:33

hrrm... now it's actually working. I must have mistyped something before otherwise I would have never done that async channel workaround

bbss16:10:21

I think I am hitting the same problem as @joshfrench just described so I am expecting that "you will want to write your query and then use the different pull selectors depending on what you have in hand" is relevant.

dnolen16:10:58

@bbss: yes sounds like it

dnolen16:10:09

it’s not possible to run union queries directly against a Datomic like thing

dnolen16:10:26

figure out the entities then pull on those

bbss16:10:59

Thanks, I'll try to figure it out over the weekend simple_smile

bbss16:10:41

I imagine datascript queries will be very useful when moving components around while making a windows metroUI-like card thing where the components are connected in complex ways

bbss16:10:13

I might also be better off just using clojure but want to experiment anyways.

drcode17:10:28

Is it allowed for the root component to be stateless, with stateful children, so that the root component just gets elided out for queries?

tony.kay17:10:24

@drcode: The query has to compose to root....Root doesn't have to actually need any of that data itself

tony.kay17:10:17

e.g. roots job would be to state what all of the children want, and then pick those pieces out and "pass them around" to the children.

tony.kay17:10:19

David can possibly speak to where things might be going...but I know "multiple roots" isn't on the radar yet (which is what mutliple stateful children with separate query trees would kinda be)

drcode17:10:50

@tony.kay: Yeah, that explanation makes sense- Thanks

drcode17:10:53

(but I'm still gonna try it out first and see what happens simple_smile

tony.kay17:10:59

it's your time simple_smile

exupero17:10:14

Are there any examples of using Om Next with client-side URL routing?

dnolen18:10:29

no, but they wouldn’t be so different from before

drcode18:10:36

@tony.kay: Yup, doesn't work simple_smile

dnolen18:10:57

so considering a new optional parameter to parse for path optimization

dnolen18:10:12

:read-ref (or :read-ident)

dnolen18:10:37

I’ve started emitting a warning if a query takes longer then 16ms

dnolen18:10:54

so this is similar to shouldComponentUpdate optimizations

dnolen18:10:03

if a query becomes slow you can implement :read-ref

dnolen18:10:28

:read-ref is given the ident and component query (not full query)

dnolen18:10:30

so in deep recursive UIs you can only run the exact query a component needs and nothing else

dnolen18:10:22

this idea is still stewing, so feedback, alternatives, concerns welcome

dnolen18:10:26

having to implement for every ident is annoying

dnolen18:10:44

so if :read-ident returns nil will defer to :read

Lambda/Sierra18:10:33

Whats up with Warning: Each child in an array or iterator should have a unique "key" prop ?

mattly18:10:54

@stuartsierra: that’s a react warning

mattly18:10:15

for when you have a collection of elements, React wants a way to identify them independent of the index

dnolen18:10:25

(to to disambiguate sibling nodes in the DOM - that is identify which DOM nodes are owned by which components)

dnolen18:10:40

React can’t magically figure this out so you supply a key

dnolen18:10:52

it’s common enough that in Om Next you can do this via the factory

dnolen18:10:18

(def my-thing (om/factory MyThing {:keyfn :id}))

dnolen18:10:33

where :keyfn is a function from props to unique key

dnolen19:10:50

@stuartsierra: the biggest issue if you don’t do this is that React can’t map component local state correctly

dnolen19:10:56

that will lead to really confusing bugs

tony.kay19:10:48

@dnolen: on path optimization.would you mind adding a little detail. I understand the localized query part rooted at an ident/ref, so you're suggesting we'll write a read dispatched on :read-ref that just needs to understand how to read an arbitrary subquery that is rooted at anything we've given an Ident?

dnolen19:10:14

@tony.kay: that’s exactly the idea

dnolen19:10:35

but of course want to avoid work where no perf problem exists

tony.kay19:10:42

don't we already have that by dispatching on a ref?

dnolen19:10:56

so :read-ident might require code duplication

dnolen19:10:36

@tony.kay: not really, you get ref (really ident) but you can’t really use that since at the moment you must return something that matches the query

tony.kay19:10:41

hrm. Oh right...that ident could be peppered around the UI

dnolen19:10:24

parse at the moment really does mean re-run query from the root

dnolen19:10:54

you can of course add ident handling cases

dnolen19:10:04

but there’s no mechanism for you to choose

dnolen19:10:18

that is to inform Om Next that you’re using one strategy or the other

dnolen19:10:20

that’s the problem

dnolen19:10:36

otherwise I wouldn’t bother with :read-ident

dnolen19:10:13

we could signal with a new kind of :value like thing

tony.kay19:10:15

I'm not connecting the dots on where you trigger the choice...

tony.kay19:10:22

:value-like

dnolen19:10:41

but then your parse code will definitely complect declarative logic with optimization logic

dnolen19:10:46

not so excited about that

dnolen19:10:11

and all this stuff is really unnecesary for remote parsing

dnolen19:10:19

purely a client side query issue

tony.kay19:10:32

Mmmm. This might be related...I've been pondering the issue of UI data being complected in with persistent data in the queries...lots of extra tease apart and put back together stuff I'm not loving there too

dnolen19:10:42

right you have to be careful there

dnolen19:10:05

but queries + computed give you decent tools

dnolen19:10:11

but you bottom out at taste at some point

tony.kay19:10:45

yeah, we were finding most cases could probably be handled with comp local state, prop passing, and computed...but then we move it out of app state and lose tracking

tony.kay19:10:04

(not sure we lose tracking in the final product...but at the moment we do)

tony.kay19:10:05

at least the new approach leaves it all ref transparent simple_smile

tony.kay19:10:52

So you're suggesting the trigger on mutate follow-on reads, correct?

dnolen19:10:11

@tony.kay: not following, can you clarify?

Lambda/Sierra19:10:25

If my query expressions use selectors like [{:library/books [:book/authors]}] do I need to do anything special in my read function to handle it?

tony.kay19:10:20

@dnolen: I'm trying to see how you'd work in the :value-like thing. Are you saying a parent parsing step would make the decision: "Instead of continuing down this parsing route, I'm returning this special :value-like this to indicate you should follow that parsing route instead"

dnolen19:10:46

default-ui->props would make this decision

dnolen19:10:01

nothing inside parse itself

tony.kay19:10:51

Bummer...I don't know enough about that...sounds like an index simple_smile

dnolen19:10:20

just read the source it’s like 5 lines (the other 5 is timing logic)

dnolen19:10:53

every component that needs to update will have it’s props computed via defualt-ui->props

tony.kay19:10:54

doing that...just had not yet

tony.kay19:10:55

ok, so you're saying that if some threshold is reached, this function switches approaches away from full-query?

tony.kay19:10:24

or that IF the alternative exists, it just uses it (more likely)

tony.kay19:10:41

the threshold is just trying to tell you when you might want to do it

tony.kay19:10:54

ok, I get it now

dnolen19:10:59

the threshold is just information to users

dnolen19:10:04

- "hey your stuff is slow now"

dnolen19:10:40

if a query takes longer than 16ms something is either very wrong

dnolen19:10:51

or the structure of the UI is naturally recursive

tony.kay19:10:54

oh, rightm, I thought your meant my slack responses were slow 😛

tony.kay19:10:15

yeah, I understood that

tony.kay19:10:40

@stuartsierra: You might want to read my Om overview (see pinned items)...I talk about (the current) state of affairs with respect to implementing read in detail.

Lambda/Sierra19:10:39

@tony.kay: I've been looking at that, in fact. simple_smile That's partly what prompted the question.

tony.kay19:10:34

your read function has to implement the "meaning" of that query. So I'm not sure what you mean about "doing anything special"

Lambda/Sierra19:10:04

I think I'm confused because I'm used to Datomic Pull syntax.

tony.kay19:10:22

well, if you are sending it to Datomic, you can just pass it on (unmolested)

tony.kay19:10:33

in which case you'd be doing it remote

Lambda/Sierra19:10:33

Datomic Pull follows references automatically. Does the Om.next parser not do that?

dnolen19:10:54

that’s really a question about storage

dnolen19:10:02

not about parsing - parsing is really just routing

Lambda/Sierra19:10:11

I'm just using a local map in an atom right now.

dnolen19:10:13

like literally URL routing but recursive and on data

dnolen19:10:10

Om Next has a “default” db thing if you’re not using DataScript

dnolen19:10:36

this is what’s being referred to when talking about normalization / denormalization

dnolen19:10:49

I may in fact rename these operations tree->db and db->tree

dnolen19:10:20

@stuartsierra: so if you use normalize denormalize you can get link following

dnolen19:10:35

but it’s not a feature of parse itself (because it needs to be pluggable)

Lambda/Sierra19:10:05

OK. I'm using (om/reconciler {:state init-data-value :parser parser}) as in the examples.

dnolen19:10:21

@stuartsierra: and you looked at the normalization tutorial?

Lambda/Sierra19:10:42

@dnolen: Yes, although I don't really understand what it's doing.

Lambda/Sierra19:10:17

I can see my normalized data in the REPL.

dnolen19:10:21

so it takes a tree of data with dupes in it and converts it into a something that can be used more like a database - no dupes

dnolen19:10:32

you could of course avoid these steps but then you’re just pushing it server-side like Falcor does

dnolen19:10:48

clients have CPU cycles to burn, so I made it easier to do on the client

dnolen19:10:04

(but all of this is configurable)

dnolen19:10:56

i.e. you could push datoms or a tree and just transact into DataScript

dnolen19:10:21

this is worth reading if people are looking for more rationale

Lambda/Sierra19:10:31

I think I understand the rationale.

Lambda/Sierra19:10:44

It's the details of the implementation that I'm struggling with.

dnolen19:10:55

@stuartsierra: like how it actually works?

Lambda/Sierra19:10:11

yeah, or what I need to do to get the data back out.

dnolen19:10:37

(om/denormalize selector data @state)

dnolen19:10:49

where state is the app-state atom with the normalized stuff

dnolen19:10:03

that’s what you would call in parse

dnolen19:10:36

search for denormalize here for a parse use case example

Lambda/Sierra19:10:55

ahh, maybe that's what I'm missing

tony.kay19:10:04

@stuartsierra: and note that my overview doesn't touch on normalization...all my stuff assumes you're using your own normalized data store (like Datascript). @dnolen: on path optimization, so you're saying on first render our read function returns a special :value-like that indicates "I can be updated by ref", so that future updates trigger the path optimization....or are we going to implement something declarative on the component that declares that support?

dnolen19:10:57

I’m not suggesting :value-like, I’m not sure I like that option

dnolen19:10:18

I’m suggesting supplying :read-ident option to parse like :read and :mutate

dnolen19:10:25

how it gets triggered is an implementation detail

tony.kay19:10:53

AH, when you create the Om parser....

dnolen19:10:16

and if :read-ident returns nil we switch to :read

tony.kay19:10:31

That helps. I see.

tony.kay19:10:00

So, IF a component has Ident, try read-ident. If nil, run root query

Lambda/Sierra19:10:28

Oh, of course, query has to ask for the keys that ident needs!

Lambda/Sierra19:10:08

Makes sense now.

dnolen19:10:30

ident is kind of like Om Next’s version of React’s ref but more generic

dnolen19:10:34

goes beyond siblings

Lambda/Sierra20:10:09

So I guess if I want something like Datomic back-references :foo/_bar I have to … build my own index?

dnolen20:10:38

@stuartsierra: yeah there’s no support for back-references at the moment

dnolen20:10:58

that might be a knob since you’d have to be ok with building those

dnolen20:10:43

@stuartsierra: hrm, and really if you want that DataScript would probably be a better fit

Lambda/Sierra20:10:08

OK, just trying to get a feel for what's easy and what's not.

dnolen20:10:39

@stuartsierra: yeah Om Next doesn’t have any support for real DB facilities

dnolen20:10:51

the emphasis is entirely on making it easy to drop in more capability if you want

dnolen20:10:15

and to provide something pretty minimal that would integrate easily with a remote thing

tyler20:10:32

couldn’t you get back-references by remoting to datomic on the backend? Doesn’t help with local cache but you could filter those keys through to the remote and away from the local cache (apologize for any naivety)

tyler20:10:43

in the parse function that is

dnolen20:10:49

@tyler yeah that’s what I’m saying

dnolen20:10:54

DataScript or Datomic

Lambda/Sierra20:10:06

OK, that makes sense.

dnolen20:10:46

@tyler and yes you’re exactly right

dnolen20:10:56

you could automatically remote back references

Lambda/Sierra20:10:37

And if I did that (remote back references), then the Om.next normalizer would normalize them for me, right?

dnolen20:10:21

@stuartsierra: that’s correct as long as you’ve provided a proper ident to identify dupes

dnolen20:10:30

everything should just work

tony.kay20:10:40

On optimization problem: ok, so once we've rendered the UI once we know the props that were used on each component. The assumption of Ident should be that the ident of a mounted component doesn't change over time (unless a parent query changes, in which case it would all re-render anyhow). The query is composed from there down and will change only in localized manner, so I'm still not seeing why the combination of "prior props run against Ident" combined with the subquery are not already sufficient...if you indicate (via docs) that the parser can be invoked at any point where an Ident exists I'm not seeing why you need an extra thing you pass to the parser. Are you seeing a way to optimize getting the data beyond trimming the query down to a sub-tree?

dnolen20:10:35

@tony.kay: the problem is what parse returns

dnolen20:10:42

we need to know what we’re getting back

dnolen20:10:47

optimized or not

dnolen20:10:00

everything you say is true but it doesn’t solve this problem

dnolen20:10:22

:value-blah could work

dnolen20:10:32

but then I guarantee you will have really complicated parses

dnolen20:10:47

instead of separating out the optimization stuff from regular stuff

dnolen20:10:04

that’s the other reason for timing query

dnolen20:10:12

stop wasting time optimizing stuff that doesn’t matter at all

dnolen20:10:16

i.e. if you only have :read you have a fully working thing (semantically)

dnolen20:10:20

you get a warning about a hotspot

dnolen20:10:29

you add :read-ident for a case or two. done.

dnolen20:10:41

and the optimization stuff is separate from the big real business logic

tony.kay20:10:43

right, then don't have to worry about all the other cases

tony.kay20:10:17

so why not allow a read on an Ident to return nil to indicate "no optimization present"?

tony.kay20:10:14

(perhaps I'm not thinking through the parsing flow properly)

dnolen20:10:20

Om Next can’t sort that out

dnolen20:10:23

you have to sort that out

dnolen20:10:30

thus :read-ident or :value-ident

dnolen20:10:51

picking one or the other is about aesthetics

dnolen20:10:11

but this information can’t be automatically determined

dnolen20:10:15

we’re not like Falcor

dnolen20:10:31

Falcor’s whole thing works directly on the structure of JSON objects

dnolen20:10:41

thus path optimization falls out of that

dnolen20:10:51

but our queries don’t included real structure information

dnolen20:10:00

just a basic outline

tony.kay20:10:47

That was why I was pointing at the "prior query result". It is the data. I was thinking we could tease what we needed from that

tony.kay20:10:12

prior props are hanging around

teslanick20:10:49

Maybe this is germane to this conversation, maybe not -- why does the normalization tutorial suddenly start making use of quoting and unquoting to build the query?

teslanick20:10:19

The reason isn't explicitly called out, but it's not (that) common to find it in cljs

tony.kay20:10:15

@teslanick: quoting is just about getting the query into the API without having it interpreted by the compiler. Syntax can use () which would get turned into calls

dnolen20:10:33

@tony.kay: there are just too many assumptions here

dnolen20:10:42

Falcor forces you to use their thing to accomplish

dnolen20:10:53

there’s no such restriction in Om Next

teslanick20:10:53

Query syntax can use lists? Maybe I haven't looked that deeply yet

dnolen20:10:05

how path optimization works in DataScript and Om Next may be unrelated

dnolen20:10:09

it’s up to you to sort that out

dnolen20:10:18

or whatever other kinds of local DBs people come up with

dnolen20:10:26

@tony.kay: btw not being argumentative here, happy to talk back and forth about this

tony.kay20:10:30

ok. I obviously need to study the problem further, so I'll trust you on that for now. I don't want to waste your time teaching me the detail I'm missing. Given the assumption we have to get the user's input, then I like your proposal.

dnolen20:10:34

so it’s clear why I have a certain perspective

dnolen20:10:43

and more than happy to stall while people get up to speed on the options

dnolen20:10:10

I might write up a problem page about this on the wiki

tony.kay20:10:12

thanks for saying that. I'm pretty thick-skinned, but also am at the point where it is obvious more reading on my part would be more efficient

dnolen20:10:15

and people can read over that

dnolen20:10:31

I think that’ll make things easier to assess

tony.kay20:10:40

It seems like there are basically two kinds of options: the one you propose, and one where we declare something additional on the component itself. The latter seems to still need the former, so not sure what else you'd do.

dnolen20:10:22

@tony.kay: so I’ll write up everything we covered here and the options, Falcor context, and repercussions for DataScript vs. Om Next normalization etc.

tony.kay20:10:44

that would be awesome. In the meantime I'm going to look at path optimization docs in Falcor

dnolen20:10:21

nothing here yet but there will be

tony.kay20:10:42

😄 I was thinking "D*&^ he types fast"

drcode21:10:09

Made an Om issue for a new failing case I'm running into: https://github.com/omcljs/om/issues/453 - If anyone can see an error on my part in that example, let me know ASAP so I don't have to tie up dnolen's time simple_smile

dnolen21:10:13

@drcode: what version? somebody reported a bug very similar to this one

dnolen21:10:28

was the bug

dnolen21:10:33

fixed in alpha13

drcode21:10:57

Thought I tried it on the latest 1.0.0-alpha14-SNAPSHOT but now will double check

dnolen21:10:01

(not saying it’s resolved)

dnolen21:10:25

yeah I would be extra sure you have a clean build

dnolen21:10:47

@drcode: I don’t see that bug

dnolen21:10:54

I see a bug because you’re passing nil as state

dnolen21:10:56

you can’t do that

dnolen21:10:24

(I’m running your example with 1.0.0-alpha14-SNAPSHOT)

dnolen21:10:59

oh but you’re returning something for your read sorry missed that

dnolen21:10:44

yeah ok, props look OK but the I see a different error for sure

drcode21:10:21

Sorry, my switch from alpha12 to alpha14-SNAPHOT must have gone wrong

drcode21:10:39

busted for the second time on build issues- Sorry, need to be more careful in the future

drcode21:10:00

I'm not getting any errors on alpha14, so the alpha13 fix must have done it

drcode21:10:36

@dnolen are you saying you still see an error?

dnolen21:10:02

no I also messed something up over here

drcode21:10:24

OK, thanks

dnolen21:10:06

@drcode: so it’s working for you right?

dnolen21:10:26

it’s working for me here for sure

drcode21:10:28

Yes, all looking good

dnolen21:10:42

bug reports like this still welcome

dnolen21:10:06

still too early to have any confidence there aren’t little issues here and there

teslanick21:10:03

Having trouble troubleshooting an issue: Error: function (clearly a React constructor function) is not ISeqable when attempting to normalize some data. I'm sure I'm misusing something somewhere, but I'm not sure where.

teslanick21:10:24

(om.next, attempting to adapt the normalization tutorial to a slightly different problem domain)

drcode21:10:03

So do I have this right: When om/transact! is called, I am able to tell my program what paths are invalidated, by doing [(mutation! ...) {:INVALIDE-THIS ...} {:INVALIDATE-THAT ..}]

drcode21:10:34

But I can't trigger an invalidation from within a mutation function (because the :value key is only there for documentation)

drcode22:10:01

What I'm confused about is that when I transact from a deeply nested component, I have no idea what other paths are invalidated, especially if the component is a library component. But when I'm in the mutation function I have all this information.

drcode22:10:19

I guess my question is just whether I have my facts straight

teslanick22:10:48

Found the issue: It's expecting om/Ident on a component that I don't anticipate needing it on.

teslanick22:10:58

Aha: [{ :current-planet (om/get-query PlanetDisplay)} ...] => [[:current-planet (om/get-query PlanetDisplay)] ...]

monjohn22:10:51

@teslanick: What difference does it make between using a Map and Vec?

teslanick22:10:29

Not sure I understand the vocabulary well enough to explain the difference yet. 😉

jannis23:10:43

Not sure I like the idea to inject a new field into the card data just for validation but it's quick idea.

tony.kay23:10:03

@drcode: You're tacking on "reads" to do after the mutation...the abstract is that you are saying "I want to change this, and I depend on this other stuff"..where "the other stuff" is a subset of all of the things that could have changed due to the mutation

tony.kay23:10:06

If you;ve seen the "Fat Query" stuff in Relay, it's like that. There are dozens of things that your mutation could have changed, but only YOU know which of those your current UI needs to refresh

tony.kay23:10:05

Think more in terms of the data exchange with a server as opposed to re-rendering...the re-rendering is the desirable side-effect...having the data correct in your local app state is the real goal.

Oliver George23:10:48

(Just poking around at om.next trying to ge a feel for things. thanks tony.kay for your evolving doc too) From what I can tell using om/Ident means that om/transact! will include a :ref in the mutate env. That sounds handy for giving the mutate-fn the context but I don't see any examples of this in the documentation. I wondered if it's a good design pattern or not.

Oliver George23:10:49

So, in my case, (:ref env) looks like [:person/by-name Anna]...

tony.kay23:10:11

om/Ident is partially about normalization...de-duping data

tony.kay23:10:27

So, reading David's normalization docs is a good idea

tony.kay23:10:12

As a side-effect, two components with the same Ident are rendering the "same thing", so refreshing those components when a transact is done from a component with that ident makes sense: if one changed, then the other has changed as well.

tony.kay23:10:53

Also, path optimization...work in progress...is part of that story. To be honest I'm still thinking about the other implications/flex points on Ident. For example, if you have a Car renderer that renders [:car 42], could you not also have a Vehicle renderer with the same Ident? Nothing breaks, other than the fact that the specific queries might vary in detail.

Oliver George23:10:14

Yeah, that optimisation stuff is less clear to me. Having an "ident" for mutation context seems very useful though. Else there's a lot of boilerplate around passing a pk to transact! each time. I have one project where every table's pk seems to be a unique snowflake. Nothing is ID, many are a composite key. Keeping that complexity out of the way would be nice.

tony.kay23:10:30

right, Ident has a lot to do with helping make sure all of the bits of UI that depend on the same (client-unique) thing update together

Oliver George23:10:33

One other question: has anyone done a compare/contrast with the concepts from re-frame. Just curious since that's my reference point at the moment.

Oliver George23:10:46

I'm probably focused more on how to manage business logic, REST api interactions, derived data etc. Possibly considered secondary issues for om.next just now.

tony.kay23:10:49

David might have...I can say that if you read the Relay intro docs and a bit about Falcor you'll understand what om-next is trying to do

tony.kay23:10:05

REST is not part of it at all

Oliver George23:10:06

Okay, thanks Tony.

drcode23:10:57

@tony.kay - Thanks, need to find time to read the Relay docs