This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-04-02
Channels
- # admin-announcements (2)
- # beginners (14)
- # boot (38)
- # cider (2)
- # cljsjs (3)
- # clojure (114)
- # clojure-russia (64)
- # clojure-taiwan (1)
- # clojurescript (40)
- # code-reviews (8)
- # component (2)
- # core-async (2)
- # cursive (7)
- # editors (3)
- # euroclojure (1)
- # hoplon (53)
- # leiningen (4)
- # om (129)
- # onyx (5)
- # proton (4)
- # protorepl (5)
- # re-frame (5)
- # reagent (11)
- # untangled (5)
- # yada (3)
I think get-query is wrong for when you pass in a class to it
If something implements IQuery, but is not a component, it should just go to line 261, and skip the isFunction check
hi guys, is {:keys []
in mutation function the same as the key we specify when doing transaction using om/transact!
like
(defmethod mutate 'user/logout!
[{:keys [state parser query ast target] :as env} k params]
{:value {:keys [:current-user]}
:action (fn [])})
{:on-click #(om/transact! this `[(~'user/logout!) :current-user])}
@anmonteiro: thanks for answering. I will create a minimal example later, it quite works for now
@nxqd: the {:keys}
in a parser method is there purely for documentation purposes only
Re-reads happen based on the query itself
@iwankaramazow: ah, I remember it now 馃槥 It confuses me every time. I asked this question twice already, sorry guys T_T
The logic behind is: if your team is large enough, somebody else might implement the actual mutation (I think)
It gives him an idea what is happening at the time
The docs are pretty ambiguous about this 馃槃
@nxqd: ps do you have an idea how I can set the this.props.children
of an om component?
nested routing 馃檲
No idea if this could even work with query composition, but I'll give it a try
@iwankaramazow: http://anmonteiro.com/2016/02/routing-in-om-next-a-catalog-of-approaches/
@nxqd: I have a set-query approach working right now, I'll experiment further
@taylor.sando: it's not wrong, that part is needed for advanced compilation
@thiagofm: taking a long break, going for a run, lifting some free weights afterwards (no machines) & revisiting the problem a week later
What's the problem?
It's with IQuery params. I have the children component Code with: static om/IQueryParams (params [this] {:language nil :repository-full-name nil}) static om/IQuery (query [this] '[{:repository {:query ?language}} {:code {:language ?language :repository-full-name ?repository-full-name}} :language :repository-full-name]) and the parent: (defui Window static om/IQuery (query [this] [(om/get-query code/Code)]) Object (render [this] (dom/div nil "Hello world" (game-window-comp (om/props this))))) There wasn't any dispatch happening to the read :repository
I mean, there was, but it was breaking. It was trying to dispatch to the read as {:repository {:query nil}}, which doesn't exist as om/dispatch just get the key
So I've written my own "om/dispatch" to in this case, get the key of {:repository {:query nil}} and do the dispatch
The problem I think is that I'm using "everything": set-query + remote + everything... so I can't really have a sharp idea of what is going on and why
I recommend starting again with the simplest things: solely a read, then gradually add everything back
I have a (om/set-query! this {:params {:language "ruby" :repository-full-name "rails/rails"}}) for example, but it doesn't seem to work
having a valid query will also help
[(om/get-query code/Code)]
is not valid
What would be valid in that case? I want to get all the queries from the Code component
Aggregate the query into a join
[{:code (om/get-query code/Code)}]
should work
@thiagofm: it seems that you still don't understand the basic Om Next concepts. as such, and answering your first question, going through the tutorials again would be my suggestion
I went through them a couple of times already, they cover basic examples and usually a bit different from what I want
I don't understand why I do need to make a join, when I don't really have to. I already have the queries in my sub component, I just need the data
If queries in subcomponents worked, I would never have to do it. It isn't as a sql join. The term join there at least sounds a bit misleading to me
it's a join in the sense that you're joining data in that key
so it's almost a synonym to what a SQL join is
think of it as a modularity thing
let's say you have a clojure program
your core
namespace requires namespaces my-project.foo
and my-project.bar
it's the same in Om Next
your root component needs to "require" the queries of your sub components
I get it better now, thanks. But then what do I do with the reader for that join? I get the value for some query value?
all of the data must come in from the top - into your root component - and it is the total query that works out what this data is. total query is applied to your app state. The top query is always a whole load of joins (and maybe some direct keys as well)
what you do with the reader for that value depends on what you want to do... I'm not the one to say
The read
has to go down to the next level - recurse to the keys that are in the query that it has. i.e. a key has a query that is composed of keys.
I see. But then the children component will access the result of the parent component query, instead of the queries it provided?
Like this: (let [{:keys [repository language repository-full-name ]} (:code (om/props this))] ?
So a read method invokes more reads, using its query. Usually you just call db->tree
so it is easy. However with parameters it is hard and I am battling with that at the moment.
@thiagofm: if your Root declares a query [{:foo [:some :other]}]
, you want to pass (:foo (om/props this))
down to the component
not the whole props
@anmonteiro: for that case, it's a sub-sub component, so I pass the whole props because I don't even know what will be the queries that special component needs, but it's good to know that
@thiagofm: you should never pass the whole props down
the point of having queries is that you know exactly what you need to pass down...
@anmonteiro: okay, I'll fix it up
I think it's a bit misleading that you set up the query in the children component, but it will never function as query of the root component. Maybe it's worth having om/SubQuery or something that would let people know the difference between them
I can't get the tempids
working. I have understood the default merge function should replace the tempids with real ids, if I just call the reconciler send callback with correct format. I'm calling the callback like this: (cb [['todos/add {:tempids {[:id temp-id] [:id 123]}}]])
. Still, the id in the state atom is the temp id, not 123. Is the format correct? Is there anything else I should do instead of just calling the callback?
@anmonteiro: but thanks a lot for taking your time to explain this to me. Now I have plenty of new things to try
@rap1ds: did you set up :id-key
in the reconciler?
@anmontoire Yeah, I tried that also, I set it to :id-key :id
In the Quick Start guide it says that the :value
map in the mutate function can contain two keys, :keys and/or :tempids. Is that something I should look into?
what you're passing to the callback seems correct
I'm just wondering why it's not a map
Not sure if relevant, but my Todo component, the ident is implemented like this: (ident [this {:keys [id]}] [:todo/by-id id])
So the app state atom contains list of IDs in todos
and then the todo/by-id
map.
that's expected
so what happens if you call it like this? (cb {'todos/add {:tempids {:id temp-id :id 123}}})
@anmonteiro Is this correct? {:id temp-id :id 123}
Or should it be {[:id temp-id] [:id 123]}
?
I tried this (cb {'todos/add {:tempids {[:id temp-id] [:id 123]}}})
and it's still not working. The tempid is still there... I'm starting to wonder if there's something else wrong with my code... hmm..
This is how I fetch the temp-id
:
(let [
{[children] :children} (om.next/query->ast remote)
temp-id (get-in children [:params :id])]
I guess that's the right way to do it?I've been trying to learn from this example: https://github.com/griffio/om-next-04/blob/master/src/om_next_04/core.cljs#L27
@rap1ds: yes, you're right, typo in my example
@rap1ds: mayb have a look at this example: https://github.com/awkay/om-tutorial/blob/ece4adc30216d2fdfdb9317729d9ecb7388762fd/src/cards/om_tutorial/om_specs.cljs#L14
@anmonteiro: Cool! I will look at that. Thanks!
@anmonteiro: so, with the previous example of Code(children component) and Window(root comp) and :code join of a couple of queries of the code component. Inside the read :code, what should I do? It seems that I don't have the results of running the query, do I have to call some function inside the read?
I can see the params that I set from set-query now: #object [cljs.core.Atom {:val {:language "ruby", :repository-full-name "rails/rails"}}], and also inside the read I have the ast, but the ast doesn't have anything about the just set-query. I can't really fetch anything inside the read as I've expected 馃槥
@thiagofm: Your question is the basically the same as what uwo was trying to do earlier, if I'm not mistaken.
So the key you have made up (for the root component) needs a read. And that is hard to do. I'm in the same boat. Trying to solve the problem uwo has.
Inside the read from the root component(:code): My ast has: {:type :join, :dispatch-key :code, :key :code, :query [{:repository {:query nil}} {:file {:language nil, :repository-full-name nil}} :language :repository-full-name], :component haxlife.components.code/Code, :children [{:type :join, :dispatch-key :repository, :key :repository, :query {:query nil}, :children [{:type :union, :query {:query nil}, :children [{:type :union-entry, :union-key :query, :query nil, :children []}]}]} {:type :join, :dispatch-key :file, :key :file, :query {:language nil, :repository-full-name nil}, :children [{:type :union, :query {:language nil, :repository-full-name nil}, :children [{:type :union-entry, :union-key :language, :query nil, :children []} {:type :union-entry, :union-key :repository-full-name, :query nil, :children []}]}]} {:type :prop, :dispatch-key :language, :key :language} {:type :prop, :dispatch-key :repository-full-name, :key :repository-full-name}]} My state has: #object [cljs.core.Atom {:val {:language "ruby", :repository-full-name "rails/rails"}}] As you can see, it isn't merged, queried or anything. I can't see how this becomes something that I would have the result of the queries in my children component
The sad thing is that there's even a remote in one of the children component queries, so much things going on
@cjmurphy: are your read queries inside the children components running? If I add console.log inside of it, nothing is printed. It seems that the queries aren't getting called anymore
Is there any way to call a read from inside a another read and get its result? I guess this is what we're missing, but doing this looks weird
(defn recursive-read [{:keys [query parser] :as env} _ _]
{:value {:local-value :x
:other-value (parser (assoc (dissoc env :query)) query)}})
Yes - you call the parser - calling the parser with a query is basically doing a read.
My problem is I don't know where the query parameters are or how to pass them down. Or even if I have to - b/c I don't know how IQueryParams figgers into all of this. (actually I kind of do - just sorting this stuff out...)
so do the particular symbol keys in {'app/save {:tempids ...}} matter with the defaults? or just a way to mark :tempids maps?
@cjmurphy: can you access the params you set with set-query in the read from the parent/root component?
That's more than I know. I can tell from this kind of code that the params are to be found in the ast:
(defn send-to-chan [c]
(fn [{:keys [search]} cb]
(when search
(let [_ (println "WANT happening: " search)
_ (pprint (om/query->ast search))
{[search] :children} (om/query->ast search)
user-query (get-in search [:params :user-query])]
(put! c [user-query cb])))))
I'm playing with nested remote reads and no recursive parsing. building an ast-zipper, walking and finding all the nodes which require remote read. then I have a collection of asts, and {:type :root :children remote-asts}
seemed like the natural way to use them
generally seems strangely limiting that it's expecting only a QueryExpr, not QueryRoot, there. am I confused, though?
which one would be more idiomatic? I could either have a top level query [{:ui ...}]
in my root component that constructs the entire UI in one read fn. Or several smaller queries for each top level component with a corresponding read fn for each?
@seanirby: depends on the size of your app, how it is going to evolve, how many people are working on it
Just do what feels best at the moment
iwankaramazow: well I wasn't considering it from that perspective. its just a personal project . Both have tradeoffs in readability, but I haven't measured the performance difference yet.
@anmonteiro: is it possible to compose multiple queries under one join?
i.e. I'm extending my router to handle nested routes, the idea is to aggregate all queries of children under :root
let [sub-query (reduce #(if-let [query (om/get-query %2)]
(into [] (concat % query))
%) [] components)]
(into [] (concat [{:route [:router-stuff]}] [{:root sub-query}]))
components
is a vector of components that match a given route.example result: [{:route [:router-stuff]} {:root [:main/title {:navbar/items [:name :href]} :overview/count]}]
This should be valid, shouldn't it?
would :main/title
be in a different component than :overview/count
?
[:main/title {:navbar/items [:name :href]}]
is a component and [ :overview/count]
is a query from another one
I hoped I could join them under :root
then not valid
if you want to join several queries under one key, use a union
ah ok, thanks for the help, feared this