This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-04-04
Channels
- # beginners (31)
- # boot (24)
- # braid-chat (17)
- # cider (4)
- # cljs-dev (33)
- # cljsrn (5)
- # clojure (79)
- # clojure-austin (1)
- # clojure-poland (229)
- # clojure-russia (51)
- # clojure-uk (3)
- # clojurescript (68)
- # core-async (1)
- # core-matrix (1)
- # datomic (18)
- # editors (24)
- # emacs (7)
- # hoplon (118)
- # jobs (1)
- # jobs-discuss (1)
- # juxt (7)
- # off-topic (16)
- # om (121)
- # onyx (3)
- # parinfer (224)
- # protorepl (3)
- # re-frame (29)
- # reagent (1)
- # rethinkdb (2)
- # ring (1)
- # spacemacs (2)
- # untangled (182)
init state should work like this in on.next
(initState [this]
(println “init state”))
, is it correct?It is initLocalState
You can see the lifecycle methods, and their arguments here: https://github.com/omcljs/om/blob/ee0fb19c4b32c1bf4a7b10f2644e8adf681f8d12/src/main/om/next.clj#L41-L48
@anmonteiro: (cc @cjmurphy) Ok, so I’ve thrown together the Autocomplete tutorial code and added a root component with a read method that attempts what I understood you to be suggesting on Saturday. Obviously the autocomplete works if it is the target of add-root!, but once it’s the child of a Root component it becomes unclear to me how to compose the query. https://github.com/uwo/om-params
@uwo: it looks like your :search/results
read method is not going to be called in your code above. Only the :root-query
read will be called
@seanirby: This one doesn't work either:
(defmethod read :root-query
[{:keys [query parser ast] :as env} k params]
(println "The user's query is in the ast: " (-> ast :children first :params :user-query))
(println "The query is already as we need it to be: " query)
{:value {:root-query (parser env query)}})
This obviously calls it but the the remote logic is never handled at the root level. so recursive parsing seems kinda off the table (would have to share remote logic)
(defmethod read :root-query
[{:keys [parser query] :as env} k params]
{:value (parser env query)} )
@uwo why do you think that implies recursive parsing is off the table? can't you just call the parser again from :root-query if needed with different args?
i haven't had to do it myself yet but i think you mess around with the read-tracking parser from here you'll see how it can be done
@isak: you’re right I shouldn’t say off the table, but after sharing this with anmonteiro a couple of days ago, he discouraged me from going the recursive route
uwo: i'm also unfamiliar with recursive parsing. can you not do his other suggestion and put the logic in :root-query
seems like it would be a good use case for it, though i'm just getting into it. I was going to go this route to handle client side routing and subqueries
because i'd still want to spread out my read logic as normal even though everything gets composed from a root query
@seanirby: actually strike what I just said, the Iquery would still live on the component
@seanirby: when I asked him about taking that approach he responded that it was best not to: https://clojurians.slack.com/archives/om/p1459549857002290
@uwo: after looking at the concrete example, it seems that what I said might not be exactly true after all
I'm thinking that a recursive parsing approach would probably help here
(defmethod read :root-query
[{:keys [query target parser ast state] :as env} k params]
(let [val (parser env query target)]
(if (and (= target :search)
(not (empty? val)))
{:value (select-keys @state [:search/results])
:search (om.next.impl.parser/expr->ast (first val))}
{:value val})))
changing the read method to this works in your example
hm! thanks! so for all components that require query params they’ll need to be a comparable read method on root?
I wouldn't say that's always the case
so what happens if we need to read more than one thing from :search in :root-query? I had thought once that recursive parsing would make it work, but I don't see how
@tomjack: what's the root-query?
would it make sense to call the parser recursively, then pick out the :value from the parser result recursively, and merge it into the top level :value map that will be returned?
in om-params the root-query is like [{:root-query [(:search/results {:query "foo"})]}]
but say we want [{:root-query [(:search/results {:query "foo"}) (:other-search/results {:query "bar"})]}]
@tomjack @iwankaramazow it’s updated to use https://clojurians.slack.com/archives/om/p1459789318002520
ah it's just the autocomplete example from the tutorial?
I'll run it locally to check the result
@iwankaramazow: except it nests the autocomplete in a root component
ok, I'll take a look at it 😄
I’m curious if this will become an unwieldy requirement in an app that has a lot of components with dynamic queries.
@uwo: I see what you mean, almost finished here
just gotta modify the send function
This might be a little tricky 😄
give me 10 more minutes 😛
anyone tried this with :query-root true
& om/process-roots
?
@iwankaramazow: why process-roots
? we aren’t dealing with client local keys, no?
My idea was to return {:search (assoc ast :query-root true)}
in the read of :search/results
This way we can rewrite [{:root-query [(:search/results {:query ""})]}]
to [{(:search/results {:query "test"})]}]
Or at least om could do it for us 😄
however, I'm doing something wrong at the moment
second
I'll let you know when I've found a solution
@uwo: solution https://gist.github.com/IwanKaramazow/ac22bf8653ce9274292c6bf993d9cc9f
The only thing I changed:
(defmethod read :root-query
[{:keys [parser query ast target] :as env} key _]
(let [search (parser env query target)]
(if (and target (not-empty search))
{:search (update-in ast [:query] (fn [query] search))}
{:value (parser env query)})))
(defn send-to-chan [c]
(fn [{:keys [search] :as env} cb]
(when search
(let [{[search] :children} (om/query->ast (get-in (first search) [:root-query]))
query (get-in search [:params :query])]
(put! c [query cb])))))
ah ok never mind then 😛
ah I see, anmonteiro already provided one
(om.next.impl.parser/expr->ast (first val))
is in fact much cleaner
my first instinct was to call the parser recursively on the :root-query
key, and then use process-roots
yeah, what I was curious about was having to write essentially two read methods for each dynamic query, one with the actual logic and another to compose with root
that's pretty much the case
there are some places where you have to compose queries in joins or unions to make valid queries
the logic of
(defmethod read :root-query
[{:keys [parser query ast target] :as env} key _]
(let [search (parser env query target)]
(if (and target (not-empty search))
{:search (update-in ast [:query] (fn [query] search))}
{:value (parser env query)})))
will mostly be the same in all those casesindeed helper fns will save you
haha oh yea
no idea what I was thinking
@tomjack: have you tried the [{:root-query [(:search/results {:query "foo"}) (:other-search/results {:query "bar"})]}]
version?
anmonteiro's version does (first val)
and uses that for expr->ast, but that will throw away part of the query if there is more than :search/results
I am working with that patch to om above on my project, so eager to learn whether the patch makes sense or whether I'm doing it wrong
I'll try it first
did you duplicate AutoCompleter
with :other-search/results
in the query?
just one autocompleter, with
'[(:search/results {:query ?query})
(:search/other-results {:query ?query})]
same params for both searches?
ah you kept just one search input?
https://files.slack.com/files-pri/T03RZGPFR-F0XQFLRHR/-.diff against f309494 in om-params
no idea yet, I'm copying your code 😛
by forcing the send to handle exprs {:root-query [...]}, you can stuff multiple things in the ...
why don't we do:
(defn search-loop [c]
(go
(loop [[query cb ] (<! c)]
(let [[_ results] (<! (jsonp (str base-url query)))]
(cb {:search/results results
:search/other results} ))
(recur (<! c)))))
In a more real world situation, you wouldn't write (cb {:som-key "results"})
:som-key
is extremely dynamic
in most cases, om would know under which key it would need to merge, or at least you supply it (most often dynamically)
Example:
(defn send-to-chan [c]
(fn [{:keys [search] :as env} cb]
(when search
(let [{[search] :children} (om/query->ast (get-in (first search) [:root-query]))
query (get-in search [:params :query])
key (get-in search [:key])]
(put! c [key query cb])))))
(defn search-loop [c]
(go
(loop [[ key query cb ] (<! c)]
(let [[_ results] (<! (jsonp (str base-url query)))]
(cb {key results} ))
(recur (<! c)))))
I think I realized something: in JS React, nothing says the props
passed to a child have to be part of the same data structure as the parent's props
. The parent is free to create new props
and pass them to the child.
It's only in Om.now using cursors that you care if the child's props
came from the same data structure as the parent's.
If you don't use cursors, a parent component can safely generate props
for its children, right?
Or you could create new props on-the-fly in a call to om/build
for example.
Am I missing anything?
@stuartsierra: you can create new props without a problem either way (other than potential overrendering), though if you do pass down a cursor and props, you end up wrapping the cursor, so you just have to be careful to destructure the cursor before doing transact calls in the child component
@isak: By “wrapping the cursor,” do you mean that Om.now will always wrap props in a cursor, even if that cursor has no root Atom to link to?
no, i mean if you send some props to a component inside a map, then you have to make sure to treat it that way and not like a cursor
ah, yes
an example is the first one on this page: http://annapawlicka.com/common-mistakes-to-avoid-when-creating-an-om-component-part-2/
Right. If you want to use the cursor, you have to pull it out of whatever data structure you passed as props
.
thanks
for om.next remotes, is it normal to have a lot of read methods, or just a few? i'm doing it now and i'm leaning towards just one, even though the client will have quite many
Or is this what (om/build … {:opts {…}})
is for?