Fork me on GitHub
#om
<
2016-01-28
>
samueldev01:01:19

Apart from this gist which doesn't seem to work as intended, I can't find many examples of using secretary w/ om-next https://webcache.googleusercontent.com/search?q=cache:lWqltnThWUIJ:https://gist.github.com/24ba8c404708c452b0de+&amp;cd=3&amp;hl=en&amp;ct=clnk&amp;gl=ca

samueldev01:01:29

anybody have any good examples anywhere?

samueldev01:01:38

also the cookbooks are out of date and use om.old 😞

tawus03:01:17

@samueldev: AFAIK, routing is still evolving for om.next. Here is the design document https://github.com/omcljs/om/wiki/Routing-Support. Here is one example https://github.com/andrewboltachev/omnext-routing-one/ but it does not use secretary.

jimmy03:01:34

hi guys, what is the best way to embed global state like jwt token in every request ? I can see that om only takes care of the query. So the best way would be http header then ?

cjmurphy04:01:07

Are there any examples of the components (their ident and query methods) and denormalized data to make a table view? I am struggling with how to structure two locations and four gases. The table view I would like to see has gases along the top and locations down the left side. One way of thinking about the data is that there are two master-detail relationships: location->cell and gas->cell. Obviously the cell is the location/gas combination and there are eight of these. The first thing I'm trying to get right and failing at is automatic normalization (I can see the result with (pprint @reconciler)). I can put together a gist of what I'm been trying, but this is such a common thing to want to do I'm hoping there might be an example out there already.

jimmy05:01:21

@cjmurphy: please put up a gist. I want to find out how this should work too, haven't played with ident yet

jlongster06:01:57

finally playing with db->tree; any obvious reason this isn't denormalizing? https://gist.github.com/jlongster/bd88d9199a362677dbb3 (ignore the :list/transactions nil bit)

andrewboltachev06:01:57

@jlongster: I were looking at it some time ago. Let me check

jimmy06:01:16

@jlongster: thanks for explaining the part of process-roots btw simple_smile

andrewboltachev07:01:25

@jlongster: For me worked only this way:

om-ui.core=> (om/db->tree '[*] (:list/transactions (:transactions @reconciler)) @reconciler)
[{:from_acct [{:balance 0, :id 4, :name "income"}], :id 1, :to_acct [{:balance 0, :id 1, :name "bank of america"}], :amount 3.5, :date 1453243176928} {:from_acct [{:balance 0, :id 4, :name "income"}], :id 2, :to_acct [{:balance 0, :id 2, :name "chase"}], :amount 7, :date 1453243176928} {:from_acct [{:balance 0, :id 4, :name "income"}], :id 3, :to_acct [{:balance 0, :id 3, :name "credit"}], :amount 12.1, :date 1453243176928} {:from_acct [{:balance 0, :id 4, :name "income"}], :id 4, :to_acct [{:balance 0, :id 1, :name "bank of america"}], :amount 9.44, :date 1453243176928}]

andrewboltachev07:01:09

Is there's a way to define if particular bound query (with QueryParams applied) is "instance" of unbound one?

andrewboltachev08:01:38

@tawus: I have improved my routing example so that it uses core.async channel and componentDidMount event/method inside which set-query! works properly (inside Om Next there's binding in play, and thus set-query! acts differently in different places). It still uses one hack, this one: https://github.com/andrewboltachev/omnext-routing-one/blob/master/src/cljs/omnext_routing_one/core.cljs#L96 This is fake key (which readf would just return nil for) which is used to identify component by it's query. For a reason, metadata can't be used here (to do the same).

iwankaramazow09:01:10

@jlongster: this is the general pattern of an om/db->tree

(om/db->tree query (get @state key) @state)
Let's say you want the :from-account with the state from your gist.
query = [:from-account]
(get @state key) = (get-in @reconciler [:transactions :list-transactions])
@state = @reconciler
Applied to your gist: (om/db->tree [:from_acct] (get-in @reconciler [:transactions :list/transactions]) @reconciler) The docs say: `Given a query, some data in the default database format, and the entire application state`. How I remember it: the 'default database format' has to be a function which returns something in the format [[:transaction/by-id 1] [:transaction/by-id 2]] The query pulls everything it specifies, after the 'default-database-format' aka [[:transaction/by-id 1] [:transaction/by-id 2]] has been replaced with it's ident.

nblumoe10:01:25

When using update-query to set the query params on a subcomponent, is it expected to trigger a root render? And thus also resetting the params to the initial, static values?

nblumoe10:01:09

(I researched the chat history and closely related issues popped up repeatedly, however, I was not able to figure this out.)

andrewboltachev10:01:31

@nblumoe: I were experiencing suchlike things (setting to initial values). Where are you using it from?

andrewboltachev10:01:01

i.e. from render or somewhere else?

nblumoe10:01:33

well, just calling update-query! from a click handler (on a button within that rendered component)

andrewboltachev10:01:32

what's 1st parameter?

andrewboltachev10:01:43

this or MyComponent?

andrewboltachev10:01:35

oh well that's legit then

andrewboltachev10:01:51

I were calling set-query! from outside and it worked stange

nblumoe10:01:54

ok, so that's expected behavior? I should instead call this how to make it re-render only that instance?

nblumoe10:01:32

(or did you mean "it should be working" with "legit"?)

andrewboltachev10:01:57

I did mean that it wouldn't necessarily not work then simple_smile

nblumoe10:01:18

hahaha, gotcha

iwankaramazow11:01:50

Man, I'm really struggling with routing. My UI is completely build bottom-up, more like tinkering small components into a structured whole. Routing on the other hand is top-down.

jimmy12:01:53

@iwankaramazow: you can try out this approach of routing through this template https://github.com/anmonteiro/aemette/

iwankaramazow12:01:50

Thanks, didn't know it existed 😄

nblumoe13:01:46

I could get my queries with params on a subcomponent to work by using subquery instead of get-query. However, still the Root component is being re-rendered on every change on the subcomponent's query params, which I would like to avoid. ;(

jannis13:01:56

@nblumoe: Just a thought... does the subcomponent have an Ident?

jannis13:01:13

If it does, perhaps path optimization could help here? Note: this is just me guessing, it may not actually help at all.

nblumoe13:01:36

@jannis: the subcomponent itself does not. But it has children that habe Idents

nblumoe13:01:53

any more specific pointers what you mean with path optimization and how it could be related?

jannis13:01:39

If a component has an ident and :pathopt is enabled, it allows you to run queries against that ident/component independently of the root query. Normally, you would only get new props for the component by re-running the root query (e.g. after transactions) and passing the new props down. With path optimization, for idents like [:item/by-id 5], there would be a (defmethod read :item/by-id ...) function and it would only re-run that where possible. I'm not 100% sure how good/accurate this explanation is. The reason I was thinking it might be useful: if it would only re-run the [:item/by-id 5] query when doing update-query! it would not rerender your whole app. I'm not sure if it works that way though.

nblumoe13:01:27

ah good to know. thanks a lot for the explanation

jannis13:01:22

@nblumoe: There's no documentation for this yet but there is a devcards example and a test for the :item/by-id read "shortcut" in the Om repository.

jannis14:01:27

@nblumoe: I've only used it in one experiment so far: https://github.com/Jannis/custard/blob/master/src/web/components/nodes.cljs#L42 - here I have a component that represents [:node <ID>] and whenever the transaction to expand/collapse the node, only read :node is re-run, not the entire root query. This speeds things up quite a bit.

newtocljs14:01:08

hi I'm trying to use OM together with SVG , this project is the blueprint im using: https://github.com/Hendekagon/hello-om-svg/blob/master/src/hello_om_svg/ui.cljs#L2

anmonteiro14:01:40

@dnolen: regarding #592, there's an alternative way: in factory, add a reactKey to props and read that in the react-key function

dnolen14:01:58

@anmonteiro: yes something like that is preferred

dnolen14:01:13

anything that we might need to change due to React releases is undesirable

anmonteiro14:01:26

@dnolen: I tried that first but thought that reading directly from where it was in React would be preferred

newtocljs14:01:27

now I defined a new component for a hexagon which look slike this: http://pastebin.com/KKvACWQ8 but when I try to run it I get a this: WARNING: Use of undeclared Var hello-om-svg.ui/polygon at line 20 src\hello_om_svg\ui.cljs and the component doesn't show up

dnolen14:01:44

@anmonteiro: accessing into internals is just a huge pain in the butt

dnolen14:01:55

we inherit version churn from React - do not want.

anmonteiro14:01:20

@dnolen: that becomes clear now, I'll do it another way then

anmonteiro14:01:32

btw is there something pending about #436 or did you just forget to close it?

dnolen14:01:31

@anmonteiro: ah, thanks, just missed that one

dnolen14:01:34

closed now

jlongster14:01:44

@iwankaramazow: ah, of course thanks. you can also query from the top and just pass in the top-level state to both args (om/db->tree '[{:transactions [{:list/transactions [:from_acct]}]}] @reconciler @reconciler).

jlongster14:01:51

shouldn't [{:list/transactions [*]}] get all props?

jlongster14:01:12

s/props/fields/

anmonteiro14:01:29

@dnolen: alright, just submitted #594 which uses the alternate approach

jlongster14:01:26

Here's an example of [*] not working, what am I doing wrong?

galleon.reconciler=> (om/db->tree '[{:transactions [{:list/transactions [:amount :id]}]}] @reconciler @reconciler)
{:transactions {:list/transactions [{:amount 3.5, :id 1} {:amount 7, :id 2} {:amount 12.1, :id 3} {:amount 9.44, :id 4}]}}

galleon.reconciler=> (om/db->tree '[{:transactions [{:list/transactions [*]}]}] @reconciler @reconciler)
{:transactions {:list/transactions [{} {} {} {}]}}

jannis14:01:55

@jlongster: Om queries != Datomic/Datascript pull queries.

jannis14:01:41

@jlongster: Have you tried just [{:transactions [:list/transactions]}]? If that doesn't work you'll have to specify a query for the :list/transactions join. It can be recursive and/or come from another or the same component of course.

jlongster14:01:56

@jannis just tried it, it doesn't denormalize it. so there's no way to get all fields of a list of normalized data? I could have sworn I've seen [*] in some tutorials. Not a big deal, I'm just learning in depth right now, don't actually have a use case

anmonteiro14:01:47

trying out your example now

jlongster14:01:07

@anmonteiro: I can make a gist for clear STR if you need it

jannis14:01:15

Oh, [*] is a thing in Om? Cool simple_smile

anmonteiro14:01:32

@jlongster: I'd appreciate it, esp. a piece of data I can use with that query

jlongster14:01:44

copied that data from my state which Om normalized, should be correct

jlongster14:01:24

I'm on 1.0.0-alpha28

jlongster14:01:37

maybe I should try alpha30 actually, I think that's the latest

anmonteiro14:01:02

@jlongster: so I'll just try it quickly in alpha 30 and let you know

jlongster14:01:32

too late, just tried simple_smile still seems broken

anmonteiro14:01:45

@jlongster: working for me actually

jlongster14:01:55

oh! ok, I'll try again

jlongster14:01:03

oops didn't refresh the page

anmonteiro14:01:36

@jlongster: there were some changes in db->tree between alphas 28 & 30

jlongster14:01:53

@anmonteiro: ok, thanks. still doesn't work for me actually, weird. are you running master, or definitely 30?

jlongster15:01:15

I may not have upgraded correctly (something still cached etc)

jlongster15:01:35

@anmonteiro: ah yep I had to blow away my build dir to make everything recompile again, sorry

cjmurphy15:01:22

Just from the Kanban example code, the denormalized:

:lanes [{:id 10} {:id 11} {:id 12} {:id 13}]
, turns into:
:lanes
   [[:lane/by-id 10]
    [:lane/by-id 11]
    [:lane/by-id 12]
    [:lane/by-id 13]]
But how about if I wanted just one, say: :secret-lane {:id 11} I tried it and it doesn't give me an Ident, but stays as {:id 11}

jlongster15:01:46

:secret-lane [{:id 11}] ?

cjmurphy15:01:06

Just made up that keyword.

cjmurphy15:01:22

Sorry - has to be in a vector.

iwankaramazow15:01:33

that query syntax doesn't look valid

cjmurphy15:01:15

Its the 'original-state' - denormalised state, not a query.

iwankaramazow15:01:53

a vector doesn't do the job?

cjmurphy15:01:12

Making it a vector doesn't help. Seems like you have to use matching keyword names and :secret-key does not match anything.

cjmurphy15:01:22

vector gave:

cjmurphy15:01:22

:secret-lane [{:id 11}]},

cjmurphy15:01:33

Same thing back.

iwankaramazow15:01:43

:secret-lane is described in an ident somewhere?

cjmurphy15:01:04

That's a very good point.

cjmurphy15:01:20

I think there would have to be a secret-lane component.

iwankaramazow15:01:21

@jlongster didn't know you could query from the top. Interesting!

easystreet15:01:55

alpha30: why is BarChild's render method getting called here after the transact!? https://www.refheap.com/114181

nha16:01:20

In om.next (inside tony awesome tutorial), I am trying to understand the korks argument of set-state! and update-state!. I tried the following :

(om/update-state! this [:checked] ;; tried also :checked
                  (fn [l]
                    (prn l) ;; nothing printed
                    (not l)))
;; the following two equivalent implementations work
(om/update-state! this #(update-in % [:checked] not))
(om/set-state! this {:checked (.. e -target -checked)} )

nha16:01:21

Alright had a look at the source (https://github.com/omcljs/om/blob/master/src/main/om/next.cljs#L566), I don't need that .

alasdair23:01:13

Hello, basic question ~ does om.next support more than one root component on a page? I have tried this and only the last component added gets updates and I see the docs mention "the" root.

futuro23:01:13

Are you adding multiple roots to the same page element?

futuro23:01:03

because it should support adding multiple roots to the page, so long as you attach them to different elements

alasdair23:01:04

no, separate divs with individual ids ~ it's something I've done in the current om, quite handy.

alasdair23:01:19

ok - in that case it's probably me

alasdair23:01:01

I wasn't sure of the basic operating model

alasdair23:01:55

I have only just started looking at om.next and may well have missed something - thanks for the confirmation that I'm not trying something unsupported.

futuro23:01:46

reading through om.next/add-root! it looks like it should work

futuro23:01:53

full disclosure, I've never tried it

alasdair23:01:22

The om.next doc for app-root reads "Return the application's root component." which implies either 1. there is only one root, or 2. one of the roots is special

alasdair23:01:37

which got me wondering

futuro23:01:48

hmm...good point

futuro23:01:00

reading the source, I think the docs might be misleading

alasdair23:01:08

I hope it does support multiple - I have used multiple roots so the page editor can position the active elements

alasdair23:01:46

ok - I shall have a (slow) read

futuro23:01:25

So if you have one reconciler, then "application's root component" is accurate, because each reconciler has one root component, and your app only has one reconciler

futuro23:01:15

but if you have multiple, then app-roots doc string would read better as "Return the reconciler's root component."

alasdair23:01:06

(defn add-root! "Given a root component class and a target root DOM node, instantiate and render the root class using the reconciler's :state property. The reconciler will continue to observe changes to :state and keep the target node in sync. Note a reconciler may have only one root. If invoked on a reconciler with an existing root, the new root will replace the old one."

alasdair23:01:22

so one root per reconciler

futuro23:01:19

from observing the channel, having one reconciler per app is the approach it seems many people are taking

futuro23:01:45

and using set-query! and some other things to change child-components inside that one root

futuro23:01:52

to alter what's being shown on the page

futuro23:01:10

So keep that in mind while reading some of the docs

alasdair23:01:21

I will have a play with a shared atom and focus more on the source for docs ~ thanks for that guidance.

alasdair23:01:03

three roots, three reconcilers, common atom seems to work ok with my little test app.

alasdair23:01:09

so I guess that is the way to go for the use case where you have multiple "standalone" components that can share the same state.

futuro23:01:10

That's what I've been doing so far.

alasdair23:01:22

I guess the denormalisation a reconciler does is for the use of components under the same root.

alasdair23:01:39

or rather - that's it, no guessing

ethangracer23:01:51

just noticed that an error thrown from a parser’s read function will propagate to the environment running om, while an error thrown from a parser’s mutate function does not propagate. rather, it is caught by om and converted into the response from the mutation. does anyone know why this is the intended behavior? Is there a built-in handling mechanism for pulling out and re-throwing the error?