This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-02-11
Channels
- # announcements (1)
- # beginners (84)
- # boot (325)
- # cbus (1)
- # cider (13)
- # cljs-dev (1)
- # cljsjs (1)
- # cljsrn (15)
- # clojars (8)
- # clojure (221)
- # clojure-czech (2)
- # clojure-ireland (8)
- # clojure-madison (28)
- # clojure-poland (176)
- # clojure-russia (111)
- # clojurebridge (7)
- # clojurescript (75)
- # community-development (70)
- # conf-proposals (19)
- # core-async (29)
- # css (12)
- # cursive (66)
- # datavis (15)
- # datomic (61)
- # devcards (15)
- # dirac (2)
- # editors (13)
- # emacs (9)
- # funcool (7)
- # hoplon (13)
- # jobs-discuss (5)
- # ldnclj (39)
- # ldnproclodo (1)
- # lein-figwheel (3)
- # leiningen (21)
- # liberator (26)
- # off-topic (12)
- # om (153)
- # onyx (168)
- # parinfer (165)
- # proton (21)
- # quil (5)
- # re-frame (58)
- # reagent (4)
- # ring-swagger (12)
- # spacemacs (3)
- # yada (120)
is there a detectible difference in the parser for when a read is part of a transact!
vs add-root!
/ set-query!
?
@hueyp: I think that in the AST the :type keyword is set to :call on a mutation...someone can correct me if I am wrong on that one...
but for the reads in the transact! query, e.g. [(user/set-name {:name “Bob” }) :user/name]
— the :user/name
parse
I guess the idea is to use force
to mark them … but not sure why transact!
reads don’t default to force?
yah, might be barking up the wrong tree … just thinking of what information to use when deciding whether to cache a read. Like if I transition routes, I’m cool not hitting a remote for anything already in the local state, but if I do a transact!
I want to make sure I always send remotes … I kind of view the reads in transact!
as existing for exactly this purpose
Hi everyone: I'm a bit confused by what types of "reads" are supported by om/transact!
... In the documentation it calls them "keys" instead of "reads" and looking at the source code it uses the term "simple reads"
I have a transaction as follows:
(om/transact! reconciler '[(do-this {}) {:read [:inner-read]}])
Am I correct in think that this is not a "simple read" and that I instead can only write:
(om/transact! reconciler '[(do-this {}) :read])
In other words, are "reads" other than atomic keywords supported? (I ask because I can't get more detailed reads to work)you can have joins in those reads too. the distinction is that not all queries are … not sure the proper word, but ‘root’ queries
for instance [:id :name]
is a legit query, but might not have enough context to parse … the parser might have a key :current-user
… so the [:id :name]
query on a component would be pulled into a root query
so I’d say [:id :name]
is a simple query, and [{:current-user [:id :name]}]
is a full or root query or whatever the non-simple term is
@hueyp: Thanks- that's how I thought they worked as well, thanks for the confirmation (it's seems like the logical expectation that you can have arbitrary reads, as long as they are rooted) now I still need to figure out why it doesn't seem to work that way for me...
and to add to that … when you transact!
, om is going to transform those reads by walking to the root … the exact mechanics I’m not 100% sure of, but if you have two components, [{:current-user (om/get-query Child)}]
and Child transacts!
with a key of :name
it might resolve into a full query of {:current-user [:name]}
but its smarter than just that … I’ve had it notice that the key isn’t in the direct components query, but in the parents query, and it worked out fine … so I have that on my list to really understand
which seems to go against documentation, so I want to double check .. but I think that happens
actually it might not go against docs at all, maybe if its not indexed it feels free to remove it
okok, so there's a bit of black magic there after all that might be tripping up my transactions... that's probably what I'm running into...
> it might also remove read keys from a transact!
too
Yup, that's what seems to be happening, and I can't figure out why...
I don’t know exactly whats going on … I just remember testing by putting a fake key into a transact!
and it didn’t survive
@hueyp: Yes, it seems like the correct action with a garbage key would be to throw a parser error, not just sanitize the query
yah, so if I do: (om/transact! this [(todo/toggle {:id ~id}) :completed? :random-key])
it turns into transacted '[(todo/toggle {:id 1}) {:current-user [{:todos [:completed?]}]} {:current-user [{:todos [:completed?]}]}]
… the :random-key
is gone
my assumption is that :random-key
is not indexed so it gets taken out … but I need to check the code … clearly it was just me trying things out
Yes, that's the cause of my confusion in a nutshell, I see the same weirdness... I assume it's because the transactions go through the indexer in a "bottom up" fashion, causing the resulting query to be very ugly, but technically correct (As long as you are doing everything else correctly)
I couldn’t actually get that above to reliably work … e.g. [(todo/delete {:id ~id}) :todosCount :todos]
gets turned into [(todo/delete {:id 1}) {:current-user [:todosCount]} {:current-user [{:todos [:id :text :completed? {:author [:id]}]}]}]
which has :current-user
twice as a root key the parser just overwrites the value
so instead I tried: [(todo/delete {:id ~id}) {[:person/by-id author-id] [:todosCount {:todos (om/get-query Todo)}]}]
that results in: transacted '[(todo/delete {:id 1}) {[:person/by-id 1] [:todosCount {:todos [:id :text :completed? {:author [:id]}]}]}]
Yeah, all sensible advice, thanks for this info, I feel like I am at step 27 of the 100 steps of Om Next mastery now
a lot of this stuff doesn’t matter unless you have a remote … local state just re-running ui->props
hides any data synchronization problems you might have
but if you need remotes to be synched, you have to figure out how to make om send the right reads
but you can make a sample app which has local state and no reads in transacts and it works great
@hueyp: FYI, your advice was spot-on... followed your thinking and it fixed all my problems- Thanks!
(om next) Hello, I have a component nested inside another one. The main one has a query to [:game/tutorial], for example. That query works perfectly and returns the desired output. But the nested component have the same query specified and (om/props this) returns nothing. Anyone knows what could be happening?
@thiagofm: Is your query composing to the top? (i.e. by om/get-query
)
iwankaramazow: no, very straightforward stuff, like this: http://pastie.org/10718130
'[lambdas/total]
-> '[:lambdas/total]
just a guess, but make sure you're using keywords if your parser handles keywords
I'm using the exact same query of another component, which retrieves results, but this one doesn't, it just returns nil for om/props
hmm, if another component has that query and gets its props
just pass those props down to the child
the query on the child is redundant
@iwankaramazow: I'm just using the same query because it doesn't work for any query. I actually wanted to use a different query
do you have a link to the project? (github?)
@iwankaramazow: https://github.com/thiagofm/haxlife it's using chestnut, so even to run it is easy. So, both the Window and Player components are the same, but in the Player component, the query doesn't run (it prints just nil, while the other prints {:game/tutorial #{[1 false]}})
One detail is that I'm using Datascript, the queries you can find in haxlife/data/query
Window
is your root, you're not passing any props down
(tutorial-comp id)
(game-window-comp)
only id
get's down
the root-query 'injects' the result as props on the root component
Why do I need to pass the props down? If I (game-window-comp 1) it still doesn't work 😞
I admit I'm a bit lost. But if I'm querying in the Player component, shouldn't this be enough by itself?
If a component deep inside the tree has a query, your have to compose it to the top with om/get-query
on the root-component
The root-component will get the result of that query as props
then you have to manually pass them down
no way around this
I'll write some example code
(defui Window
static om/IQuery
(query [this]
[(first (om/get-query Player))])
Object
(render ...))
Window is your root-component, Player a child. This is an example of the query composing to the top.
@dnolen: updated wiki docs to reflect the computed
docstring about replacing previous computed props. here's the diff: https://github.com/omcljs/om/wiki/Documentation-(om.next)/_compare/29efb387dd2eba77afc1a5eae0d8edfbcd60ad5d...cedf53506ff37e5d318bb24eca437c68c554df40
@iwankaramazow: your example is wrong because Window is stealing Player's props
@thiagofm: it'll contain the full query, that might be a long query 😛
Okay, great. I guess this is written in "Components, Identity & Norm...", I've read all the docs multiple times, but I'm just really getting it now that I'm writing stuff down.
Just remember that a child when implementing IQuery
, doesn't get the result from it's query, it gets the result trough props passing down the tree
I quite like this approach though, if I could query separately in each component it would feel as everything had some sort of state
If I recall correctly, Relay/GraphQL injects props at without you passing down the props from the root
In the beginning the notion of passing everything down seemed a bit strange at first, but it hasn't given me any problems (yet 😇) )
@iwankaramazow: any special reason of why you used the first function on (first (om/get-query Player)) ?
@anmonteiro: looks good to me
@thiagofm: would be [[:game/tutorial]]
without (first ...)
, with it gives you [:game/tutorial]
just making sure the query is valid
@iwankaramazow: just a last question, I guess. the Player component is deep down, how can I reference it? I have to require its file? Wouldn't this create a circular dependency error?
@thiagofm: no, you should require Player in Window. Only if you also require Window in Player you get a circular dependency
So, om-next is pushing my (rather limited) clojure skills. As soon as I moved my app-state, read, mutate and reconciler definitions to a separate namespace (weather-project.state) I started getting this error:
No method in multimethod 'weather-project.state/mutate' for dispatch value: weather-project.ios.core/zip-change
Sure enough, if I change the definition from:
(defmulti mutate om/dispatch)
(defmethod mutate 'zip-change
[{:keys [state]} _ {:keys [zip-text]}]
{:action
(fn []
(swap! state assoc-in [:zip] zip-text))})
to
(defmulti mutate om/dispatch)
(defmethod mutate 'weather-project.ios.core/zip-change
[{:keys [state]} _ {:keys [zip-text]}]
{:action
(fn []
(swap! state assoc-in [:zip] zip-text))})
It works. But how can I reuse that method if I have to explicitly define what namespace the function will be called in?
(om/transact! this `[(zip-change {:zip-text ~zip-text})])
How should I be quoting it?
Yeah, the quote doesn’t work:
weather-project.ios.core=> `[(zip-change {:zip-text "asdf"})]
[(weather-project.ios.core/zip-change {:zip-text "asdf"})]
weather-project.ios.core=> `[('zip-change {:zip-text "asdf"})]
[((quote weather-project.ios.core/zip-change) {:zip-text "asdf"})]
Ah, it’s tilda quote
(om/transact! this `[(~'zip-change {:zip-text ~zip-text})])
Oh yeah, zip/change is much easier to read.
Yeah, makes sense. Thanks @hueyp!
I need a little conceptual guidance. The root component composes a query which populates the state for the whole app. If I want something to be requested from the served afterwards, conditional on a child component being mounted, where should I do it? (or what should I read?)
Probably in your parser
check out the item, how can I delay loads
@iwankaramazow: thanks, I read that but couldn't figure it out. Is :loading
somehow a special value to om.next?
@bensu: :loading
is the possible value v
of the destructured 'response' from (find @state key)
😄
not om specific
it just means you can conditionally delay loads based on your app-state
maybe you could put something in your state indicating that the component is mounted
for example :is-mounted
@iwankaramazow: I get it. Thanks! That is not what I'm going to do though, I'm going to use the same condition I use to decide if the component should be mounted in the first place
Keep in mind root-query gets composed even if components aren't mounted
(correct me if I'm wrong)
that's the reason they are static
I encountered that one on more than one occasion 😄 Not sure how it should be fixed without concrete code.
It might be related to the fact that the smallest component specifies a query which its parent is not currently using
Can I get a small datascript help? I'm trying to update the value of the key :lambdas/total to it + 1 (I don't want to use inc, because this 1 will become something else after)
haxlife.data.db=> conn #object [cljs.core.Atom {:val #C07V8N22C/DB {:schema {}, :datoms [[1 :game/tutorial false 536870915] [2 :lambdas/per-character 1 536870914] [2 :lambdas/per-second 1 536870914] [2 :lambdas/total 0 536870914]]}}] haxlife.data.db=> (update-in (d/db conn) [2 :lambdas/total] #(+ % 1))) #C07V8N22C/DB {:schema {}, :datoms [[1 :game/tutorial false 536870915] [2 :lambdas/per-character 1 536870914] [2 :lambdas/per-second 1 536870914] [2 :lambdas/total 0 536870914]]}
hello people
I gotta into a situation that I'm wondering if it's responsability of my code or it should be done by Om.next
I have a query that looks like this:
considering that on initial load the :categories
are not available, it's going to be loaded on the first remote request
the query rewrite seems to work fine, it removes the :menu
from the game and add it back on the rewrite, making the server response being like this:
when this response is merged, all the categories are propertly identified and added to the index, which one gotcha
the :categories
key itself (which should contain a list with refs for the categories) never gets into my local state
then I wonder if it's a bug (meaning the Om.next should be able to recognize the [:categories _]
and add it into the root of my state with the list of refs) or if I need to manually handle this before merging
so, Om.next is supposed to handle the merge on those situations?
@grzm: I didn't confirm that it works with inc. After having too much issues doing the update I'll do just a select + update, it's just a pet project, not worth fighting too much against something I'll have learned better later
anyone can help me with the IDisplayName protocol? i’m trying to debug some code and it would be very helpful. i implemented it this way:
(defn simple-component [data owner]
(reify
om/IDisplayName
(display-name [_]
"simple-component")
om/IRenderState
(render-state [_ _]
(dom/li nil (:name data)))))