Fork me on GitHub
#om
<
2016-02-04
>
johnswanson00:02:52

it has something to do with how i’m changing the state, as replacing the :action thunk with a simple logging statement doesn’t throw an error

johnswanson00:02:19

hm, the same error occurs if i grab the source from the components, identity, and normalization tutorial and compile with :advanced optimizations

skardan10:02:58

I have a question regarding Om/next. Imagine you write an app with two tabs with two kind of items (Foos and Bars) which corespond to data on remote. How would you implement following scenarios?

skardan10:02:07

1. Refresh button. You are on Foo tab, you press refresh button. Button triggers X and om/next makes a query to server and table of Foo gets updated What is X? A transaction? A query with the parameter {:refresh true}? Setting state or query on Foo table?

skardan10:02:19

2. Server push. You are on Foo screen and server pushes updates with changes of Foo. Then you switch to Bar tab and you shoud: a. ask server to stop sending Foo updates b. get recent data about Bar c. ask server to start pushing news about Bar How would you implement it? Using remote queries? Using external go thread and call transact on state? Where you put state if it should track changes in Foo or Bar?

skardan10:02:35

I can produce several solutions, but I am curious which solutions you would consider more Om/nextish.

bplatz12:02:48

@skardan: X is a query. Transactions are for mutations. Your read function will redirect that query to the server on an as-needed basis (based on your logic). You do this with remotes, so taking a look at information about remotes is what you want.

bplatz12:02:51

As for #2, your logic on what your 'subscription/push' information needs to send or not send is entirely up to you, om doesn't get into that. It gives you a way to get that data merged into the state when it comes in, and will handle the necessary re-renders for you... but what comes in when is your call.

skardan12:02:36

@bplatz: add #1 what I am trying to achieve is to distinguish "local query" and remote query

skardan12:02:07

when I want to query localy, I would query {:foo [:a 😛 :c]}

skardan12:02:43

but for refresh, I need something like {(:foo {:force-remote true}) [:a : b :c]}

skardan12:02:53

so {:force-remote true} has to live somewhere, either in app state or component state

bplatz12:02:21

Ahh, so your normal 'logic' to determine if you need remote access wouldn't apply. You want to go to server regardless?

skardan12:02:21

i tried to do use transact without mutate operation (ie only for reread) but {:force-remote true} got lost

bplatz12:02:37

If so, there is a force call that was introduced not too long ago.

skardan12:02:03

nice! I missed that, thank you!

bplatz12:02:27

It is pretty new...

skardan12:02:03

I guess documentation has to catch up

bplatz12:02:37

Well, it is documented... just not common. simple_smile

bplatz12:02:01

So not in a typical tutorial.

skardan12:02:42

I mean it should be put in a context. You do not learn language by reading dictionary (well, actually I tried to learn scheme just by reading R4RS; without exposure to FP ideas it was not best start...)

skardan12:02:10

anyway, thank you very much for pointing me in the right direction!

frankie12:02:10

Is table referencing tables supported in om next as of alpha-30? I mean a component whose children have an om/Ident whose children have an om/Ident

frankie12:02:36

in my code om normalizes the data for the first level but the nested level is left denormalized

anmonteiro13:02:10

@frankie: I think that should work

anmonteiro13:02:17

do you have all the right idents in place?

anmonteiro13:02:38

if your answer is yes, I'd ask you make a minimal case showing how it doesn't work for you

frankie13:02:59

Thanks, I was unsure wether that was supposed to work and it’s just me doing something wrong

frankie13:02:06

I’ll reproduce that in a minimal project

cjmurphy13:02:19

I get the same problem as @frankie (I believe).

cjmurphy13:02:04

This [file](https://github.com/chrismurrph/om-alarming/blob/master/test/om_alarming/master_detail.cljs) contains all needed to demonstrate. Rendering in browser should show the x and y but does not.

cjmurphy13:02:08

master -> detail -> detail (the last detail is failing)

frankie13:02:16

@cjmurphy: I’m sorry to disappoint you, but I just extracted a minimal case, and saw tree->db working brilliantly with nested components

frankie13:02:26

As always it was my fault rather than om's

cjmurphy13:02:45

oh good I think.

cjmurphy13:02:46

I'll check check check some more...

cjmurphy13:02:20

I suspect mine will work if I do a query for the last detail (Point) at the root component. I just don't really understand why I have to do it. It is like the lanes in the Kanban demo. The Lane query is done at the topmost level and it is disconcerting that it has to be.

cjmurphy13:02:30

Yeah the extra (third level) query at the root makes it work, just like Kanban demo. To me it seems wrong I have to do it.

frankie13:02:32

@anmonteiro: ok but this looks like a bug to me https://gist.github.com/frankiesardo/7a872fe787a59f2dd631

anmonteiro14:02:43

@cascada-io: looked at your example, it's not a bug

anmonteiro14:02:11

you're transacting on the parent component, and that's the component that's going to be queued for re-render

anmonteiro14:02:26

the props have changed so it'll render its both children

anmonteiro14:02:46

if you transact! on FooChild only that one will be re-rendered, and everything works as expected

anmonteiro14:02:05

@frankie: will look at that in a sec

cascada-io14:02:43

anmonteiro: hmm, not how i would have expected. i understand that the parent will "render" all of its children, meaning that it will call BarChild again. but since it's calling with unchanged props, BarChilds shouldComponentUpdate should return false and its render method should not be called, no?

anmonteiro14:02:16

@cascada-io: will have to confirm that

cascada-io14:02:32

for me, that's kinda like one of the fundamental value props of om (`shouldComponentUpdate` optimization ootb)

frankie14:02:53

thanks anmonteiro I appreciate the time you take to answer our noob problems simple_smile

anmonteiro14:02:17

@cascada-io: you were right, I've found the issue and will submit a patch

anmonteiro14:02:38

this is also related to what @hueyp was talking about yesterday about wrapped vs. unwrapped props

bahulneel14:02:01

@anmonteiro: Thanks, exactly what I was looking for.

anmonteiro14:02:18

@bahulneel: referring to?

bahulneel14:02:49

@anmonteiro: You answered a question for me yesterday and I only just saw your response.

cascada-io15:02:42

@anmonteiro: awesome, thanks for looking into it. btw, i suspect this PR that was never merged may have been in reference to the same bug: https://github.com/omcljs/om/pull/492

anmonteiro15:02:48

@cascada-io: yep, but that fix is not quite correct though

ulsa15:02:20

I'm looking at om-next-starter. It works fine as it is, with alpha14 and 1.7.145. Its mutator returns the (old?) format :value [:app/title]. I change it to the format I assume is the new correct one, :value {:keys [:app/title]}, and it still works. A little surprising, but that's fine. I go up to alpha23, and it still works. However, on alpha24+, it fails, saying app/update-title mutation :value must be nil or a map with structure {:keys [...]}. Isn't it already? What am I missing?

ulsa15:02:17

Same happens with alpha30, so it appears it's nothing specific to alpha24.

ulsa15:02:53

Doh, forgot to change the server mutatef as well.

ulsa15:02:30

OK, so that was a silly mistake on my part, but how about this? I change the clojurescript version from 1.7.145 to 1.7.170, and I get No such namespace: cljsjs.react.

hugod15:02:37

I’m seeing reconcile errors trying to update a leaf component (an item in a list): No queries exist for component path (navigator-repro.core/ObjsViewComponent navigator-repro.core/ObjsRowComponent). Any idea what’s wrong? Minimal example https://github.com/hugoduncan/navigator-repro/tree/feature/just-list-view-web

anmonteiro15:02:13

@hugod: doesn't seem like a bug

anmonteiro15:02:59

your queries have to compose to the root

hugod15:02:05

@anmonteiro: what would that look like in this case?

anmonteiro15:02:27

@hugod: your ObjsViewComponent needs to get the query of the row

hugod15:02:54

@anmonteiro: using [{:objs (om/get-query ObjsRowComponent)}] doesn’t seem to change anything, so I expect that isn’t the correct way of expressing the change

anmonteiro16:02:26

@hugod: it should be, I think

hugod16:02:01

Is using get-query required, or is it just a convenience to not have to repeat the queries as literals?

anmonteiro16:02:35

@hugod: should be required so that Om knows the component path

anmonteiro16:02:18

@hugod: your problem is the data shape

anmonteiro16:02:18

why not use a vector?

hugod16:02:36

@anmonteiro: I wanted to make updates simple

anmonteiro16:02:08

@hugod: your queries need to match the data shape

hugod16:02:07

@anmonteiro: It isn’t clear to me how to achieve that. [{:objs {_ ~(om/get-query ObjsRowComponent)}}]?

hugod16:02:35

using that the error becomes No queries exist for component path (navigator-repro.core/ObjsViewComponent navigator-repro.core/ObjsRowComponent) or data path [:objs "a”]"

hugod17:02:38

Is this just a question of finding the correct value for query, or am I needlessly fighting with om.next by using a map rather than a vector?

mdhaney17:02:20

I've been working on a prototype with Om-next and the company likes it, but we need to make the functionality available to several teams that aren't using Clojurescript. What we want is to have a core library of components handling the Demand Driven Architecture aspects and then other teams can use those components to build out the ui's with plain React/JavaScript.

mdhaney17:02:53

I have a couple of ideas on how to do this, but want to get feedback from anyone else who may be doing this.

mdhaney17:02:46

Approach 1: basically the approach Relay takes, in that I would provide factory fns to wrap their component with an Om component that feeds data to the wrapped component. Straightforward, but I see a lot of headaches, I.e. keeping the tree in the right shape so the query fragments compose in the right way.

dnolen17:02:02

@mdhaney: @puppybits does something like this at Capital One

dnolen17:02:26

only a couple of people there work with ClojureScript everybody else just writes JavaScript against the “main” thing

dnolen17:02:48

you might want to ping him, he blogs a lot and he hangs out in the #C03S1L9DN channel

mdhaney17:02:31

@dnolen: thanks David

mdhaney17:02:40

@dnolen: the other approach I've thought about is having 2 parallel trees of components, the "data" tree with all my data components, and then a parallel UI tree. When a UI component needs data, I would dynamically build a link/ref to the underlying data tables. More work, but seems like it would be very flexible.

hueyp17:02:32

@anmonteiro @cascada-io thanks for looking into that

hueyp17:02:44

the shouldComponentUpdate thingy 😜

jlongster17:02:00

@dnolen: woha anyone around Richmond VA? we have a big capital one presence here and I know a bunch of people there

dnolen17:02:27

@jlongster: I never talked to any working on Level Money other than @puppybits and Dave Fayram

donmullen17:02:28

@mdhaney: puppybits posted several articles on medium regarding Capital One approach : https://medium.com/@puppybits

edpaget18:02:54

I'm working off the latest master (so I could try @anmonteiro's fix for OM-598) and I think I ran into a couple bugs, just wanted to clarify

edpaget18:02:29

1) in the OM-598 Pull Request right here: https://github.com/omcljs/om/pull/599/files#diff-7e4043f05bbd8e76d2da4614c2566cfaR1526, root is my root component instead of the root component class

edpaget18:02:09

2) When I have a query that has a joined child query like this: https://gist.github.com/edpaget/da4ba528057301d252c4

edpaget18:02:42

the child component doesn't get added to the class-path->query key, giving me the "No queries exist..." error

edpaget18:02:54

I think I have a fix for the second error

edpaget18:02:11

but I'm not 100% show to write/run tests in the current om setup

edpaget18:02:23

and I wasn't super sure that the second case was a bug or expected

hugod18:02:35

It looks like I have finally understood https://github.com/omcljs/om/wiki/Components,-Identity-&amp;-Normalization and have my simple example working. I found the :list/one. :list/two parts of the wiki article to needlessly complicate things.

jlongster18:02:13

How it that possibly complicated? It's the most basic example of normalization

dnolen18:02:46

@jlongster: heh, well I can’t say I know how to best explain it yet simple_smile

dnolen18:02:01

@hugod it might be helpful to understand what you conceptually tripped up on

dnolen18:02:14

I know a lot of people struggle with it even after going through the tutorial - eventually it clicks

dnolen18:02:26

I’d be happy to hear ideas about how to make it click sooner for people

jlongster18:02:01

guess I already knew the problem & the general idea, so it was ok for me

hueyp18:02:11

I’m trying to find the scenarios where om will parse to check for sends … transact! is one, add-root! is one … any others? 😜

hueyp18:02:35

oh and set-query!

dnolen18:02:22

@jlongster: right so if you looked at Falcor or have been at the React thing for a while I think you see much more quickly what problem it solves

hueyp18:02:45

I think the Falcor screencasts, walking through jsongraph, are really well done

hueyp18:02:01

in terms of another resource

jlongster18:02:19

yeah, the learning curve for Om is pretty steep so it would be good to have more intro stuff. I'm probably interested in helping with that at some point, too busy for the short term tho

hueyp18:02:18

one thing I struggle a bit with right now is whether namespaced keys are an alternative to nesting … e.g. {:user/name “Erik" :item/description “computer”} vs {:user {:user/name “Erik”} :item {:item/description “computer”}} … I’d generally nest things into the entity they belong to … but not sure if that is just comfort zone and not necessary for global keys

hugod18:02:48

@dnolen: i) the necessity for an explicit graph of components built using get-query in the query values. It wasn’t at all clear to me that this is a requirement. ii) the necessity of using data normalisation - I thought I could get by without, but couldn’t get that to work. The wiki page made it only seem applicable to cases where you had non-normalised data in the first place. The need for an explicit read function for each normalised data path was also not terribly clear (although on re-reading it is sort of explained)

hugod18:02:00

@dnolen: om.next also doesn’t give a lot of guidance when things go wrong. I spent a lot of time wondering whether I had things wrong conceptually, or whether I just had errors in specific expressions.

hueyp18:02:31

I guess nesting is the E in EAV

dnolen18:02:33

i) needs works, ii) is possible i.e. DataScript (which removes the need for it)

dnolen18:02:13

yes when things go wrong is known issue - hopefully we can identify typical errors and put helpful invariant calls around those places

jlongster18:02:25

I think the role of db->tree and the read function would be helpful to explain. seems like most people end up using it for the most part to leverage most of the work (you don't need an explicit read function for each normalized path)

hueyp18:02:27

you can have a few root entries, but a huge graph behind it

dnolen18:02:49

@anmonteiro: PR for OM-598 needs to be rebased

hugod18:02:11

I find the wiki pages have a lot of details that tend to hide the concepts (I know how hard it is to write these things…)

dnolen18:02:13

@hugod: there’s definitely a lot more documentation forthcoming that will move at much slower pace

dnolen18:02:31

but it will likely take even more time for that all to come together than it was to write the code

anmonteiro18:02:13

@dnolen: OK thanks, will let you know whenever I've done it

hugod19:02:47

@dnolen: I think it is mainly the concepts that I think I was missing - the stuff you take for granted simple_smile An explicit component graph, and how data is mapped on to it. I might try to write something down.

anmonteiro19:02:02

@dnolen: done

dnolen19:02:11

@anmonteiro: thanks!

anmonteiro19:02:32

cool, thanks

anmonteiro19:02:22

@dnolen: I have something I'd like to run by you about db->tree; not sure if a bug or not

(def state
  {:items [{:id 1 :stuff [{:name "something"}]}]})

(defui Item
  static om/Ident
  (ident [this props]
    [:by-id (:id props)])
  static om/IQuery
  (query [this]
    [:id {:stuff [:name]}]))

(defui Items
  static om/IQuery
  (query [this]
    [{:items (om/get-query Item)}]))

(def norm (om/tree->db Items state true))
(om/db->tree (om/get-query Items) norm norm)
=> {:items [{:id 1, :stuff [{}]}]}

anmonteiro19:02:10

it seems that the nested join should be in the result, even if not normalized

anmonteiro19:02:45

@edpaget: are you trying to call reindex on your code?

anmonteiro19:02:57

this is meant to be an Om internal thing

edpaget19:02:07

No I'm not

edpaget19:02:41

I was doing a set-query! then noticed everything disappeared from the indexer

edpaget19:02:07

I just added some debug statements in reindex and found that was happening for me

hueyp19:02:13

@anmonteiro: for OM-601 … is the idea for a root component omcljs$value was unwrapped, but for children it was wrapped?

anmonteiro19:02:39

@edpaget: it's not clear how that could happen, it would be really helpful if you could reproduce that in a minimal case

anmonteiro19:02:40

meanwhile the patch has been applied so you can use current master

anmonteiro19:02:10

@hueyp: exactly

dnolen19:02:07

@anmonteiro: needs thought - I suppose we could see that the [:name] subquery doesn’t have :component meta and we could just invoke select-keys in this case

dnolen19:02:25

don’t have time to think through the repercussions at the moment - but on first glance would seem OK

edpaget19:02:40

@anmonteiro: for sure I'll try to have for you in a sec

jlongster19:02:38

@anmonteiro: that would be great, I noticed that as well but forgot to ask about it. was surprising

anmonteiro19:02:37

@dnolen: alright, it also makes sense to me. I'll try to write some tests and example cases for it to sync in and put a fix together if that's the case

anmonteiro19:02:18

@jlongster: you're also referring to this join nesting?

jlongster19:02:51

@anmonteiro: yep was prototyping and hadn't normalized the data yet and db->tree just wasn't working because of exactly that

jlongster19:02:11

prob not many use cases in production but it would be nice for prototyping

dnolen19:02:30

@anmonteiro: I think what @jlongster said is the main concern

dnolen19:02:43

if people just leverage this they won’t normalize - and their apps will be crazy slow

dnolen19:02:19

so probably worth thinking thinking about emitting a warning or something

jlongster19:02:31

why is it crazy slow? I thought it just inhibits any useful mutations of it

dnolen19:02:53

because if you aren’t careful we can’t just restart a query from some arbitrary point

dnolen19:02:13

every time you have an ident you can run incremental queries

anmonteiro19:02:00

@dnolen: yep, we could also 1) say that it isn't supported by the default db format (which is agreeing to your idea of the warning — invariant would be useful here) 2) add an explicit flag/param/function for this specific use case

dnolen19:02:30

not excited about 2)

dnolen19:02:39

happy to see 1) since it will let more programs just work

dnolen19:02:46

but annoy users into doing the right thing

dnolen19:02:59

and if they don’t and their program is slow, we can’t be blamed 😉

hueyp19:02:01

is this only with path optimization turned on?

jlongster19:02:11

interesting, need to learn more about incremental queries, my understanding hasn't gotten that far yet

hueyp19:02:16

the restarting a query from an arbitrary point thing

anmonteiro19:02:39

not only pathopt, but also full-query, I believe

hueyp19:02:44

full-query still nests a link tho … I think 😜

dnolen19:02:50

@hueyp if you are calling db->tree on an ident you are also taking advantage of this property

hueyp19:02:12

db->tree is smart about it

dnolen19:02:13

but yes, :pathopt is the only place where it’s automatic at the moment - but there aren’t any promises that won’t change

hueyp19:02:25

pathopt is on my todo list simple_smile

anmonteiro19:02:52

@dnolen: I'd say 1) is something to consider in the short term, while 2) only if more people voice this concern and there's a specific use case for it that we're not seeing?

anmonteiro19:02:40

@hueyp: I meant that full-query, although nested, focusses a query down a specific path, eliding possibly other branches of the query

edpaget21:02:48

@anmonteiro: here's the reduced example https://github.com/edpaget/om-root-bug

edpaget21:02:16

it should just be runnable with figwheel

anmonteiro21:02:44

@edpaget: I can see the bug, thx for reporting

anmonteiro21:02:25

@dnolen: there's still a bug in the reindex patch; the fix is just one line, should I open an issue regardless, or just submit a patch?

dnolen21:02:44

@anmonteiro: I’ll just take a PR for that

anmonteiro21:02:21

thanks. Should I also think about submitting an invariant for the db->tree case?

dnolen21:02:27

@anmonteiro: let’s open an issue for that and stew on it a bit

edpaget21:02:37

thanks for looking at it! @anmonteiro