Fork me on GitHub
#om
<
2015-11-23
>
tyler03:11:03

In the remote synchronization demo, why is ast passed to :search in the read :search/results multimethod? If I replace ast with true it seems to work just the same.

simonb03:11:21

@bplatz: What's the definition of pull-ui in the example you gave? Thanks.

tony.kay03:11:05

@tyler: Returning true means you want to send that portion of the query on to the remote. Putting an AST node there allows you to modify the query in some way.

tony.kay03:11:37

the former was the original (only) way. The latter is the newer more flexible method

tyler03:11:25

where can you modify the query? It looks like when you pass either the ast or true, you end up with the same input to the send function.

tony.kay03:11:51

{ :search (assoc ast :query …) }

tony.kay03:11:02

just…you know…modify it simple_smile

tyler03:11:06

Gotcha so you would modify it in the parser

tony.kay03:11:16

in your read being called by the parser, yes

tyler03:11:33

I thought you passed the ast so you could modify it downstream thats what was throwing me off

tony.kay03:11:51

no, the AST does not make it out of the parser

tony.kay03:11:00

the return value of a remote run of the parser is a query

tyler03:11:32

So in the example, you don’t need to actually pass the ast to :search its just showing you that you can, and you could modify it before doing so?

tony.kay03:11:48

I don’t know the code you’re speaking of, but that sounds likely

tony.kay03:11:03

I have not looked at his new stuff in there yet

tyler03:11:37

ah gotcha sorry, thought I linked it in my original question but I must have forgot.

tony.kay03:11:29

yeah, I think that is almost certainly the case

tyler03:11:26

So if you modified the query string in the ast you return from a remote key, the remote parser would see the modified query?

tony.kay03:11:46

query isn’t a string…it’s edn, but yes

tyler03:11:39

Was referring to the actual query string thats getting sent to wikipedia in the example but I get what you’re saying. Thanks, I appreciate it. That really clarifies things.

paulb04:11:15

@anmonteiro thanks, just saw your message, it solved my problem! I am still somewhat confused about how transact! works, because I thought it implicitly re-rendered anything that this queries. In the function passed from Root to the subcomponent, this was passed as an argument from Root, so I thought it would re-render everything without me having to provide additional keys.

artemyarulin09:11:29

Hello, learning om-next, any tutorials or good example projects besides referenced from om/wiki?

danielstockton10:11:54

shows how to sync with a remote datomic database

artemyarulin10:11:09

well I’m going to integrate om-next with iOS application, where datomic unfortunately not a case, so the storage would be custom, but thanks in any case - currently I appreciate any examples simple_smile

danielstockton10:11:04

you don't have to use datomic but you'd have to write quite different read and mutate methods on the backend

danielstockton10:11:39

im not aware of any examples of that yet, datomic is much easier

artemyarulin10:11:00

btw - do you know how stable is om-next currently? I know it’s an alpha and API could change, but for small and simple things?

dnolen10:11:42

Trying to avoid big changes at this point, unless there's some huge problem - haven't seen that yet

thomasdeutsch12:11:56

@dnolen: I think it would be a good thing to have a "db-path" key for the parser. @tony.kay is using the env variable to store the :db-path, but as a datascript user, my env is the database atom. https://github.com/awkay/om-tutorial/blob/b9570df72f0d85c832fc576dd26aa7afbd871c76/src/main/om_tutorial/parsing.cljs#L31

thomasdeutsch12:11:40

as a datascript user, i would use the :db-path key to pass :db/id s

jethroksy12:11:16

Can someone explain the concept of "factory" in om-next, I'm having some troubles wrapping my head around the various components. 😕

danielstockton12:11:38

a fn that creates instances of a component

jethroksy12:11:27

Oh right what was I thinking

jethroksy12:11:31

Theres also this code in the Om.next tutorial under the parser section: (in-ns 'om-tutorial.core) (defn read [{:keys [state] :as env} key params] (let [st @state] (if-let [[_ v] (find st key)] {:value v} {:value :not-found})))

jethroksy12:11:26

Is there a reason find is used instead of get if the key is discarded anyway?

jethroksy12:11:47

I'm reading on my phone so its a little hard to test

danielstockton12:11:12

find returns the map entry [key value] rather than just the value

danielstockton12:11:53

but in this case, clearly the key isn't needed

jethroksy13:11:13

Okay thanks!

wilkerlucio13:11:33

@jethroksy: please note there is a difference between using find vs get on this case, for example: (find {:a nil} :a) returns [:a nil], which will pass true on the if-let, if you used get as (get {:a nil} :a) that would return nil that would make the if-let go false

jethroksy13:11:42

Ah good catch @wilkerlucio thanks!

danielstockton13:11:57

sorry, i didn't mean to highlight you again

dnolen13:11:05

@thomasdeutsch: not sure I follow, what would this value be? And what’s stopping you from tracking this yourself (honest questions).

thomasdeutsch13:11:52

@dnolen: if i call a parser in my read function, to parse the subquery - i think in most cases, i would like to tell the parser on what db/id or path in the env the parsing should take place. My env could be a map like: {:current-id 122 :db state} but i think that telling a parser on what entity/sub-tree to parse on, would be more idiomatic.

dnolen13:11:53

@thomasdeutsch: this is what :query-root is for

thomasdeutsch14:11:20

@dnolen: no way 🙃 will try this out with datascript. thanks

thomasdeutsch14:11:33

@dnolen: do i need an om-version higher than alpha23 ? because my reader in the om/Ident vector will not get called.

dnolen14:11:22

@thomasdeutsch: I do not know what you are saying

danielstockton15:11:28

what is the use-case for query-root?

dnolen15:11:15

also for running incremental query recalculation

misha15:11:51

good day, which channel is the best place to ask questions about natal and react-native?

donmullen16:11:45

@artemyarulin: there is a #cljrn channel now with people experimenting with om.next + reactnative or reagent/RN.

donmullen16:11:47

See you already aware (should have caught up with the conversation).

tomayerst16:11:59

Don’t you just love (clean-builds) simple_smile

tony.kay16:11:05

@thomasdeutsch: @dnolen I don't think that is what Thomas is talking about. He referred to my parsing code, which is tracking it's way through the default database format state path while doing recursive parsing. Query root is for talking to the server and stripping off a prefix of that path.

dnolen16:11:33

@tony.kay: not true it’s not only for that

tony.kay16:11:41

Ah, clarity is good

dnolen16:11:57

:query-root serves different purposes

dnolen16:11:12

you can set it when you call parse to indicate the query root

dnolen16:11:19

so that this can be detected and used for context

dnolen16:11:36

you can mark :query-root in AST when computing queries for sends

tony.kay16:11:22

but are you setting it in the parsing code anywhere (except at the actual root)?

dnolen16:11:33

this is how path optimization works

tony.kay16:11:52

right, but that is in ui->props

tony.kay16:11:23

at the start of the parse. There is nothing automatically done for us from our read functions when we call the parser again

dnolen16:11:37

but the point is that’s just generic concept

tony.kay16:11:53

just trying to make sure no one is expecting query-root to magically move about

dnolen16:11:57

and you can and should use it if need to inform yourself where you are starting

dnolen16:11:16

ah no, :query-root is not magically provided for

dnolen16:11:22

this is all user stuff

tony.kay16:11:49

yes, I just didn't realize you intended us to use it that way, so my examples use one I invented called :db-path

tony.kay16:11:14

as in "the path I've already traversed in the state tree"

dnolen16:11:17

and actually it’s not quite true what I just said

dnolen16:11:29

once again there’s enough code now that I can’t keep it all in my head simple_smile

dnolen16:11:56

if parse hits a key that’s an ident it will set this to :query-root

dnolen16:11:11

this is how path optimization works today

dnolen16:11:35

as far as I know no one has tried any of this stuff yet beyond myself

thomasdeutsch16:11:49

"if parse hits a key that’s an ident it will set this to :query-root " <- !

Tim17:11:47

When using get-node do we always use it like this (om/get-node owner “name-of-component”)?

dnolen17:11:31

@tmtwd: that or the keyword sugar

Tim17:11:06

what is sugar?

dnolen17:11:08

but you need to have made the ref with a keyword for this to work if I recall

dnolen17:11:27

@tmtwd: sorry you’re going to have to look at the docs and the source code simple_smile

dnolen17:11:39

until somebody gets around to trying it and adding it to documentation wiki

dnolen17:11:59

@tmtwd: otherwise ignore what i said, and yes do it that way

Tim17:11:08

cool thanks

paulb17:11:11

@dnolen I was able to fix the problem I was having yesterday by adding keys to the query expression of transact! However I don't understand why that was necessary, because my root component was querying everything that needed to be re-rendered. Using (om/computed) I passed down a function that calls transact! using the root component as the initiating component, so I thought implicitly it would re-render everything the root component queries. Why is that incorrect? sorry if that is unclear, this is the code https://gist.github.com/prbroadfoot/b8801772d2a41409ef86

dnolen17:11:16

@paulb it should work but I noticed there were some subtle issues with transact! you may want to try with master

dnolen17:11:48

as far as the bigger point about implicitly re-rendering everything used by the query - absolutely not

dnolen17:11:57

equality, state checks must fail

paulb17:11:53

ok thanks, here one string is replaced by another, so it should re-render, so I suppose it's a bug

dnolen18:11:53

@paulb there may be a bug if you try transact + update-state! but I’m pretty skeptical

dnolen18:11:02

this is how the om-next-demo works

dnolen18:11:35

@paulb I’ll update that when I get some time and then try your example as well

adamfrey18:11:17

I’m having trouble getting my :send function to be called. I’m probably doing something wrong. My app was written before :remotes were specified when setting up the reconciler, and all you had to do was return {:remote true} from the parser. I thought all I had to do was add :remotes [:remote] to my reconciler setup, but my send fn isn’t being called

adamfrey18:11:37

Is there anything obvious I’m missing in getting remotes working with Om version 23?

dnolen18:11:28

@adamfrey: I suggest going through the remote tutorial

dnolen18:11:29

it’s very short

adamfrey18:11:49

all right, I’ll take a closer look

dnolen18:11:16

I don’t write all of this documentation for myself simple_smile

dnolen18:11:21

and I intentionally keep everything short

wilkerlucio18:11:00

I have a scenario here where I have 2 different representations for the same data, how can I proper setup my query? the query: (query [this] [{:app/current-track (apply conj (om/get-query LoopManager) (om/get-query TrackLoopOverlay))}]), it works when it renders the LoopManager, but when I try to render TrackLoopOverlay I get No queries exist for component path (youtube-looper.next.ui/LoopPage youtube-looper.next.ui/TrackLoopOverlay)

dnolen18:11:31

@wilkerlucio: that query doesn’t make any sense to me

dnolen18:11:39

you should look at om.next.parser ns docstring to see what the grammar is

dnolen18:11:18

UI components must return QueryRoot or UnionExpr

dnolen18:11:26

and you cannot conj these together

dnolen18:11:31

you just end up with something invalid

dnolen18:11:06

that is query combination like that just isn’t allowed

dnolen18:11:51

ah ok so I sorry I see what you’re trying to do will make a QueryRoot but yeah you cannot combine queries like that

wilkerlucio18:11:38

my scenario is that I have one resource (track), and at the root component I have 2 components that uses different information from this same entity, one of then uses :track/loops, the other uses :track/duration (simplifying to make a point), I was trying to merge a single query to fetch data for both and then pass the same props for both

dnolen18:11:09

@wilkerlucio: you just can’t do it that way

dnolen18:11:26

Query <-> Component is 1-to-1

juhoteperi18:11:56

Is it documented somewhere that components can return UnionExpr? I was confused as the parser docstring mentions that most apis expect QueryRoot and then Union example shows query methods which returns UnionExpr.

dnolen18:11:15

@juhoteperi: not beyond the tutorial

dnolen18:11:21

it should be though

wilkerlucio18:11:28

ok, you have a suggestion on how to deal with this scenario?

dnolen18:11:43

@wilkerlucio: don’t combine queries

dnolen18:11:56

this just seems like a convenience, not something you actually need

dnolen18:11:24

or make the top level query and remove the query from below and make those components pure and query-less

wilkerlucio18:11:01

ok, makes sense

dnolen18:11:08

think about it this way

dnolen18:11:12

and you can avoid many confusions

dnolen18:11:24

Om Next needs to know which queries go with which components

dnolen18:11:41

if you start doing stuff like this obviously it’s not possible for Om Next to see the association

wilkerlucio18:11:41

yeah, makes sense, little by little getting used to it

dnolen18:11:08

there is a tension here which Relay doesn’t have

dnolen18:11:19

because in Relay queries are just syntax people won’t try stuff like this

dnolen18:11:40

in Om Next they are data so these kinds of data oriented things seem like they could work

dnolen18:11:54

but really in the general case they don’t work

Tim18:11:13

I just put this line in an app dom-node (om/get-node owner) and it throws an error Uncaught Error: Invariant Violation: findComponentRoot

dnolen18:11:42

@tmtwd: did you specify a React ref, the component also needs to be mounted

Tim18:11:18

oh okay, thanks

thomasdeutsch18:11:55

👉 translated the :query-root tree example to datascript: https://gist.github.com/ThomasDeutsch/0f31328a72255fdc07f1

tyler18:11:00

@dnolen: noticed a typo in the conditional for https://github.com/omcljs/om/wiki/Remote-Synchronization-Tutorial#code

(when-not (and (string/blank? query)
                   (<= 2 (count query)))
      {:search ast})
Should be:
(when (and (not (string/blank? query))
           (<= 2 (count query))
  {:search ast})

dnolen19:11:48

@tyler nice but can also just flip and tweak (< (count query) 3)

dnolen19:11:02

@thomasdeutsch: cool so it just worked for you???

paulb19:11:55

@dnolen no need to check my example, upgrading from alpha22 to alpha23 fixed the bug I was seeing simple_smile

dnolen19:11:07

@paulb cool yes I suspected that

tyler19:11:18

(let [query "h"]
  (not (and (clojure.string/blank? query)
            (< (count query) 3))))

;; true
Don’t you want the query not to run unless theres at least 2 chars?

tyler19:11:25

Maybe I’m misunderstanding the example

tyler19:11:41

isn’t not blank? always going to return true regardless of the count of query if its not blank? and if it is blank, what is the purpose of the count of the query?

dnolen19:11:52

@tyler sorry distracted fixed now

tyler19:11:34

💥 that makes sense

thomasdeutsch19:11:26

@dnolen: yes, it worked. But i still use the datascript pull api in my reader - can not do this for generic solution.

pleasetrythisathome19:11:48

hey everyone, partway through building a non-toy thing with om.next i'm confused.

pleasetrythisathome19:11:55

david's been saying, and my understand was

pleasetrythisathome19:11:00

that components and queries are 1-1

pleasetrythisathome19:11:06

but it seems like that's only true for the root component

pleasetrythisathome19:11:28

and that all child components props are passed into the factory, rather than parsed from their queries

pleasetrythisathome19:11:18

i understand the need to be able to get the entire application query in the root component, but does this mean that if i want user data somewhere down the component tree, i have to pass it all the way down?

pleasetrythisathome19:11:59

i had assumed that you could just write a query for the user at any point in the component tree

dnolen19:11:41

Do not confuse yourself. Most of the I said do not imply what you think they imply

pleasetrythisathome19:11:54

so is it possible to do something like this?

pleasetrythisathome19:11:10

my experiments suggest not. that you must pass props into (navigation), and that the root component (Dashboard), needs to build the entire query

pleasetrythisathome19:11:27

although some of the code around set-query! makes me think the above should be possible

pleasetrythisathome19:11:46

@thomasdeutsch: you mentioned calling the parser in read functions, are you doing that to get top level queries further down the component tree?

jlfischer19:11:47

I think yes, Dashboard does need to build the entire query there. To do that, you use (om/get-query Navigation) within Dashboard’s query, so you don’t need to repeat the query entirely or anything, but you do need to reference it.

pleasetrythisathome19:11:42

so what if multiple child components want to define the same query with different parameters?

pleasetrythisathome19:11:43

i can't have a query like this, correct?

pleasetrythisathome19:11:44

(query [this] [(:user/find {:uid "dorothy"}) (:user/find {:uid "lion"})])

pleasetrythisathome19:11:09

you'll end up with {:user {:uid ?}}

thomasdeutsch20:11:09

@dnolen: as far as i can understand, :query-root can help getting my data after a mutation. But can it help me for the initial read

(defmethod read :tree
  [env key params]
  (let [{:keys [state parser query query-root]} env
        group (group-by keyword? query)
        keywords-value (d/pull @state [{key (get group true)}] query-root)
        joins-value (parser env (get group false))] ;; this is where i need to pass a new query-root to the parser
    {:value (merge (first keywords-value) joins-value)}))  
@tony.kay i using a
:db-path
he is adding to the env.

pleasetrythisathome20:11:43

@thomasdeutsch: do you have an example of a query you're parsing with that?

thomasdeutsch20:11:41

@pleasetrythisathome: i do not think that your query makes sense. have you looked at datomic-pull for some advice? http://docs.datomic.com/pull.html

pleasetrythisathome20:11:10

yea i know datomic pull syntax well

thomasdeutsch20:11:52

@pleasetrythisathome: in your query you could use a function like [(:user/get-multiple {:uids ["dorothy" "lion"})] but if you already have a uid - why do you need a find? and why not using a lookup-ref (in datascript)

pleasetrythisathome20:11:04

sure you could definitely do what you're saying, my point was not about the particular query, but is about multiple child components that want different data

pleasetrythisathome20:11:44

say i have a root component, and two child components that both display lists of something, but maybe want to display different numbers of items, or different fields from those items

pleasetrythisathome20:11:23

it seems to me, that you currently have to merge child components queries into the root component query, and then pass the data to the child components as props

thomasdeutsch20:11:39

i would merge the queries in the parent, yes.

pleasetrythisathome20:11:54

so you might have something like this

pleasetrythisathome20:11:05

but that won't work, the second query to :messages/list will overwrite the first one in the data returned from the parser

thomasdeutsch20:11:54

it is not easy to tell. i am thinking of https://github.com/omcljs/om/wiki/Queries-With-Unions . Since this is a situation where you want to say that a MesssageDetailList is from another type as MessageOverfiewList

pleasetrythisathome20:11:46

hmm ok didn't look at that carefully enough. although in the example, the read function doesn't look like it's doing anything with the union query

pleasetrythisathome20:11:53

it's just returning the list of items

pleasetrythisathome20:11:11

regardless of the multiple subqueries in the union

pleasetrythisathome20:11:45

and then creating a dashboard item with all the data for each

pleasetrythisathome20:11:05

and then dispatching on type and creating the correct type in dashboard item, but each type (Graphic, Post, etc.) isn't getting the specific data it asks for, they'll all getting whatever data just happens to be in the item

pleasetrythisathome21:11:44

or am i reading something wrong?

pleasetrythisathome21:11:04

the parser doesn't automatically call the read function for the unions

pleasetrythisathome21:11:47

in fact, the unions break readers designed to take a query (for datomic/datascript pull for example)

pleasetrythisathome21:11:26

in the wiki example, and in the tests https://github.com/omcljs/om/blob/master/src/test/om/next/tests.cljs#L816, the reader isn't looking at the union query at all

wilkerlucio21:11:35

I was trying to minimize an issue that I was having about component updates, I end up falling back into the first example at Om.next quickstart page, and even so the component still not updating correctly

wilkerlucio21:11:58

example ready for devcards ^^^^

wilkerlucio21:11:14

did I miss something?

pleasetrythisathome21:11:52

@dnolen: it seems like unions should be read for each union case in the map, and then merged back together

bplatz22:11:51

@pleasetrythisathome: You need to handle your own query reading. Your example is perfectly valid, and one way to handle it is a recursive parser. i.e. if you had a read function that handled :message/list and returned the results of various queries, you'd be good.

bplatz22:11:29

They need to exist in different keys in the map though.

pleasetrythisathome22:11:46

@bplatz: right the different keys thing makes sense

pleasetrythisathome22:11:51

which is the purpose of unions queries

bplatz22:11:02

As you are returning a map... so the same behavior would apply if you overwrote a key in a map.

pleasetrythisathome22:11:11

so i suppose you could write conditional logic in your parser that detects whether or not the query is a union and does the appropriate thing

pleasetrythisathome22:11:34

the union example in the wiki works because of the normalization process through idents

bplatz22:11:39

I don't think you need union in your case, but I don't have a full grasp on what you are doing.

pleasetrythisathome22:11:02

which i think isn't really the way i'd think about unions

bplatz22:11:45

I'd make your query for Message different.

bplatz22:11:08

You can maybe flatten your details components, but as-is I'd do something like this:

bplatz22:11:32

[{:messages/details (om/get-query ...)} {:messages/overview (om/get-query ...)}]

bplatz22:11:20

Then in your parser for :messages/details and :messages/overview, which might use the same default read...

bplatz22:11:26

Do something like this:

pleasetrythisathome22:11:44

right but then you have to write another read dispatch method any time you want to have multiple components executing essentially the same query

pleasetrythisathome22:11:26

if you do it with unions, you would think something like this would just work, without the ident stuff

pleasetrythisathome22:11:34

>>>(defui MessageOverview static om/IQuery (query [this] [:message/title])) ​ (defui MessageDetail static om/IQuery (query [this] [:message/title])) ​ (defui Messages static om/IQuery (query [this] [{:messages/list {:message/details ~(om/get-query MessageDetail) :message/overview ~(om/get-query MessageOverview)}}]))

bplatz22:11:41

(defmethod read :messages/details
    [env key params]
    (let [{:keys [state query parser]} env
          recursive-read-value (parser env query)]
      {:value recursive-read-value}))
  

bplatz22:11:57

I just typed that... so it might not be completely accurate... but to illustrate the concept.

bplatz22:11:20

No you don't have to write more, not if you do what I just did there.

pleasetrythisathome22:11:29

actually you could have that as your default read

bplatz22:11:49

You can do whatever you want... yes.

pleasetrythisathome22:11:50

or the default read when the query is a map

pleasetrythisathome22:11:21

so the recursive read stuff makes sense, but i'd like to understand how to do something similar with unions as well

pleasetrythisathome22:11:47

in the above example, the read function would get called with the query as

[{:messages/list {:message/details [:message/title],
                  :message/overview [:message/title]}}]

pleasetrythisathome22:11:31

sorry the query portion would just be

{:message/details [:message/title],
                  :message/overview [:message/title]}

pleasetrythisathome22:11:27

so if you had a read function like

(defmethod read :messages/list
  [env key params]
  (let [{:keys [state query]} env]
    {:value (map #(select-keys % query) (:messages @state))}))

pleasetrythisathome22:11:28

or in my case (datascript)

(defmethod read :messages/list
  [env key params]
  (let [{:keys [state query]} env]    
    {:value (d/q '[:find [(pull ?e ?selector) ...]
                   :in $ ?selector
                   :where
                   [?e :message/uid]]
                 (d/db state) query)}))

bplatz22:11:37

Unless you are rendering those items as one list, I don't see why are you are trying to use a union.

dnolen22:11:47

@pleasetrythisathome: you don’t need a union

dnolen22:11:07

and you don’t need to merge into the parent if you’re willing to divide up the component responsibilties

dnolen22:11:15

SummaryView and DetailView

pleasetrythisathome22:11:15

i'm really just trying to understand the different ways you can structure data

pleasetrythisathome22:11:17

by divide up component responsibilities, you mean that the components have their own independent queries that are not included (either in the first level of the query vector, or nested somehow)

pleasetrythisathome22:11:21

of the root component

dnolen22:11:08

there was nothing wrong for example with what @wilkerlucio wanted to do earlier if he was willing to dupe query information into children

bplatz22:11:12

Using datascript I think you'll have to keep multiple reads, unless you have your database heavily referenced and mimicking part of your UI. If so, then great, a gigantic pull might work.

dnolen22:11:43

@pleasetrythisathome: and no there’s no such thing as “independent” queries

pleasetrythisathome22:11:43

so that was my initial point of confusion. it seems like the only component whose props are created from its query is the root component added to the reconcilcer

dnolen22:11:53

only queries that parents don’t care about but must collect

dnolen22:11:07

all component props are computed from queries

dnolen22:11:19

the full query defines all the props ready to be fed in at the root

pleasetrythisathome22:11:20

and all other components are constructed with their factory functions which take and set props

pleasetrythisathome22:11:58

so that's where i'm confused, it child component props aren't computed from their queries, or is there some way that gets done i'm missing

dnolen22:11:11

let’s step back a second … this is how it works

dnolen22:11:17

1) root components must have the entire query

dnolen22:11:24

2) this computes the fetched data tree

dnolen22:11:39

3) your components are assigned to take different parts of that tree (by having returned queries themselves)

dnolen22:11:54

4) the parent must respect the associations it made in its own query

dnolen22:11:03

otherwise it’s just busted

dnolen22:11:10

and isn’t handing children the props they asked for

pleasetrythisathome22:11:37

right, so say i want to get logged in user data down a deeply nested component tree

pleasetrythisathome22:11:44

i have to pass it through all of the children, right?

dnolen22:11:01

the model is a graph

dnolen22:11:13

you fundamentally don’t have the waterfall problem

dnolen22:11:18

anybody can link to anything whenever they want

pleasetrythisathome22:11:05

so those sound like conflicting statements to me

dnolen22:11:13

they are not

pleasetrythisathome22:11:20

when you say "anybody can link to anything whenever they want"

pleasetrythisathome22:11:40

i can have a component way down the tree with a query that has a top level parser key?

dnolen22:11:42

there’s a reason there are functions called

dnolen22:11:50

db->tree and tree->db

dnolen22:11:52

the reason you are saying “top level” parser key

dnolen22:11:56

which has no meaning in the DB format

dnolen22:11:06

is because parsing takes the DB and turns it into a Tree

pleasetrythisathome22:11:22

yes that makes sense. so would your suggestion for the above case where two subcomponents define different queries that use the same parser method would be to give them different keys in the root component query, and define a recursive parser for those keys?

dnolen22:11:30

or just make up app specific links and share parsing

dnolen22:11:54

[:some/view :a], [:some/view :b]

pleasetrythisathome22:11:09

alright makes sense

dnolen22:11:39

it will take a while for people to see this but many problems can just be fixed by making up links

pleasetrythisathome22:11:55

and the links are created by ident?

pleasetrythisathome22:11:07

i saw that in the union wiki

dnolen22:11:10

no you can just make them up

dnolen22:11:20

it’s just a convention

dnolen22:11:44

for remote data you may want to normalize so that’s why you need om.next/Ident

pleasetrythisathome22:11:13

and where are you using these? in place of keywords in the query syntax? and then you can just have more flexible parser dispatch?

dnolen22:11:14

but for local stuff doesn’t matter

dnolen22:11:39

@pleasetrythisathome: sure that’s one possibility but this isn’t my idea

dnolen22:11:44

this just a Falcor thing

pleasetrythisathome22:11:27

i'll dig into the falcor docs more

pleasetrythisathome22:11:40

thanks, need to percolate and play around for another day

pleasetrythisathome22:11:42

i'll get back to you

dnolen22:11:51

it will clear up how the link stuff is supposed to work

pleasetrythisathome22:11:24

cool, i'll check it out

dnolen22:11:06

there’s probably some edge cases here because people aren’t pushing the link bits very hard yet since in many of the examples thus far, they are something of an implementation detail

dnolen22:11:25

but it’s how you can get at some related information regardless of your location in the tree

lambdahands22:11:05

Hey, all. I would have posted this a few hours ago, but Slack was having issues. I added functions to the om.next API to deal with a reconciler’s history. Here’s a diff: https://github.com/omcljs/om/compare/master...lambdahands:master?expand=1 Thoughts?

dnolen22:11:13

@lambdahands: the history stuff just needs more thought than simply exposing it

dnolen22:11:26

happy to engage in discussing what I’m thinking about, but it’s not small amount of work

lambdahands22:11:44

Yeah, I figured. Those functions helped me out in the short term. I’d love to hear about it, though. I’m interested in doing something a little more challenging.

dnolen23:11:41

so this not fully formulated idea but I want users to be able to use the cache for far more sophisticated forms of state management

dnolen23:11:54

and I am interested in an api oriented around that

dnolen23:11:03

not just simple access to the history

dnolen23:11:38

for example for optimistic update

dnolen23:11:24

it would be nice to be able to get a bookmark somehow, and when the server errors, revert to the bookmarked state and show error message

dnolen23:11:17

things get more complicated in a concurrent scenario

dnolen23:11:28

some other user logs in, updating the application state

dnolen23:11:38

this information should be true no matter if you rewind or not

dnolen23:11:53

anyways lots of stuff like this

dnolen23:11:05

I foresee a considerable amount of hammock time

dnolen23:11:24

until then not that interested doing more with the history cache then I’ve done so far

dnolen23:11:56

it’s a little debugging tool - and people can hard code little helpers if they like in the meantime

lambdahands23:11:39

Hmm, definitely an interesting problem. The first image that popped in my head was a branching mechanism.

dnolen23:11:40

yeah not excited about branching at the moment (at least as default) - and like the reconciler we may just need to defer to defaults + pluggability

dnolen23:11:00

anyways don’t mean to discourage but this deep into “I don’t know” territory

dnolen23:11:11

and if “I don’t know” we’re not doing anything

dnolen23:11:20

not beyond design work and discussion, prototypes etc.

lambdahands23:11:21

That’s no problem! It’s insightful and elucidating to see and take part in these discussions and the implementations that develop. I remember a short IRC chat we had a few years ago when core.async first landed in CLJS and there was plenty of “I don’t know” back then. 😛

dnolen23:11:34

I think there’s a really cool idea here around the history cache and it would be nice to see somebody run with it

dnolen23:11:42

but I’d like to see somebody really run

dnolen23:11:23

think through common patterns in UI development that we can cover sensibly and well

lambdahands23:11:04

Absolutely. And I think the reach of om.next is on another level, especially considering my field of work which gravitates toward interaction design– lots of cases where I want to build functional prototypes which can be put in front of users and tested against many application states. I envision history playing a huge part in that.

dnolen23:11:43

@lambdahands: agreed there, probably what I will do in the near term is make sure history works appropriately for devcards

dnolen23:11:48

it’s a very nice way to work

shaun-mahood23:11:59

@dnolen: I'm curious about your thoughts on Allen Rohner's foam library (https://www.youtube.com/watch?v=fICC26GGBpg) and how it might work with Om Next. In the long term, do you see the idea of server side rendering becoming something that folds into Om Next, or is it something that should be pursued external to the core? Mainly curious because so many of the things that Om Next ties together are also things that haven't had a nice story to combine in the past, so wondering if there is also a nice way to get the idea of server side rendering in there too.

dnolen23:11:14

@shaun-mahood: I already said publicly that I would like to see something like that integrated

dnolen23:11:27

esp. now that React is doing away with the ids in the DOM

shaun-mahood23:11:19

@dnolen: Fantastic, I had this vague recollection of you sounding interested during the questions but am only now starting to process things from the conj