This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-03-05
Channels
- # beginners (3)
- # boot (205)
- # cider (41)
- # clojars (1)
- # clojure (76)
- # clojure-colombia (1)
- # clojure-dusseldorf (3)
- # clojure-russia (314)
- # clojure-sg (1)
- # clojurebridge (1)
- # clojurescript (115)
- # css (2)
- # cursive (5)
- # editors (2)
- # funcool (2)
- # hoplon (18)
- # jobs (62)
- # jobs-discuss (28)
- # ldnclj (1)
- # leiningen (10)
- # mount (9)
- # off-topic (4)
- # om (93)
- # parinfer (10)
- # proton (1)
- # re-frame (19)
- # ring-swagger (18)
Hello all. I've been reading the source trying to understand what's going on, and I'm focussing on the parser right now. I don't understand where join get resolved after the initial key match. From the looks of it, parser
maps through the root query expressions, does a read on each, and returns a map with results https://github.com/omcljs/om/blob/master/src/main/om/next/impl/parser.cljc#L186-L202 where do the join resolutions happen? please, and many thanks!
anyone know if it’s possible to parameterize a top-level read with multiple props? e.g. [(:id :type {:some :params})]
not particularly looking to use a join in this case, otherwise I would
@threepointone afaik, parser dont recurse automatically and wont resolve join, union, etc..
ah I see!
thank you very much! diving in
@ethangracer do you mean something like [(:id {:type ?type :some ?params})]
@reedho not quite, more like [(:id :name {:type ?type :some ?params})]
not sure if it’s possible, my tests are failing when using om/ast->expr
hoping to produce something like this
an alternative, using a join, might look like [({:my-data [:id :name]} {:type ?type :some ?params})]
the latter is valid, yes
you can parameterize a join
@hueyp do you know why?
the idea is I want to be able to read two different keys
and send the same parameter to both
it would be nice not to parameterize each read with the same data
I don’t know … it makes sense to me that you’d parameterize the root and then just join keys that you want … parameterizing each individual key with the same params … without context that doesn’t make sense to me
yeah, it’s a particular use case I’m running into with my app that could very well be a less than ideal design decision on my part… hard to explain or provide the code that would clarify. essentially I have no use for the join keyword, so just want to get rid of it
haha, generous of you to give me the benefit of the doubt 😬
but you just need to be careful if you are getting child queries that you don’t trample their metadata
interesting, i’ll give that a shot. i should probably just use a join but tinkering is too much fun
How do you pass a component's instance method to an event handler in Om Next? In pure JS, you can use the this
construct:
<form onSubmit {this.handlerFunction}>`
So far I have something like:
(dom/form #js {:onSubmit (fn [e] (.preventDefault e) (.log js/console "I was just submitted."))}
...which uses an anonymous function.
However, how can I do something like:
(defui Component
Object
(myHandler [e] (.preventDefault e) (.log js/console "I was just submitted."))
(render [this]
(dom/form #js {:onSubmit myHandler} ...)
without the this
construct that is only available (AFAIK) in pure JS?Whoops, that last code snippet should read:
(defui Component
Object
(myHandler [e] (.preventDefault e) (.log js/console "I was just submitted."))
(render [this]
(dom/form #js {:onSubmit myHandler} ...)
Are you saying what is given to :onSubmit
needs to be a particular varity, yet you need myHandler
to take two arguments? You could use a partial function of myHandler
to do this.
I just discovered you can use the (js* ...)
macro:
(defui MyComponent
Object
(handleSubmit [this e] (.preventDefault e) (.log js/console "handleSubmit."))
(render [this]
(dom/form #js {:onSubmit (js* "this.handleSubmit")} ...)))
@cjmurphy: no it's not an arity issue
I was just trying to figure out how to pass a component's instance method into the props of one of its children
I probably didn't ask it very clearly
So I guess you can use the (js* ...)
macro to use the this
keyword within clojurescript. That solves the problem fine, although I suspect this is not the idiomatic way to do this.
Yes look at the "Addition" section of this page: http://www.spacjer.com/blog/2014/09/12/clojurescript-javascript-interop/
Can't see it [here](http://cljs.info/cheatsheet/)
It feels like a hack to use js*
, but I actually think it makes interop code more readable to write it in its native syntax.
Come to think of it: it's probably not idiomatic to define a handler function within a component class method to begin with. It would probably be better to just make a (defn handle-function ...)
OUTSIDE of the defui
macro, and then just call it by its usual name when passing it as a prop.
@george.w.singer it seems this-as
is what you need for it
@george.w.singer: doesn't #(.handleSubmit this %)
work for you?!
@anmonteiro: no, it does not.
I also tried the de-macroed (fn [arg] (.handleSubmit this arg))
for good measure
neither work
Yet (js* "this.handleSubmit")
does work.
@george.w.singer: doesn't make any sense, I'm pretty sure I've gotten away with doing that before
@george.w.singer: just confirmed this works:
(defui MyComponent
Object
(handleSubmit [this e]
(println "handling submit")
(.preventDefault e))
(render [this]
(dom/div nil
(dom/button #js {:onClick #(.handleSubmit this %)} "Click me"))))
(def reconciler (om/reconciler {:state {}}))
(om/add-root! reconciler MyComponent
(gdom/getElement "app"))
Yes that does work
it has to... You're defining methods on the JS object prototype, so iterop must work
will post my own snippet of code
I stand corrected. I'm not sure what was going on before, but it was only working with the (js* ...)
macro. I just tried your method in 3 seperate places in my code and it worked.
You probably weren't using the .
syntax
It had to have been something like that
using the js*
macro is discouraged, as you might expect
Out of curiousity, are there any reasons other than aesthetic ones to avoid js*
?
george.w.singer: i suppose that makes it a bit more difficult if you want to modify your source programmaticaly
True, you're avoiding homoiconicity by using js*
Do om next mutations occur in order? I.e.: [(first-mutate-one) (and-then-mutate-two {:param "val"})]
?
Will those mutations happen in order on all remotes?
from reading Om's source that seems to be the case
correct me if I'm wrong
george.w.singer: from my reading of the parser source, yes, i don’t know if that is spec’d though
it looks like the action fns are all called in a reduce. how do remote mutations work?
if you start some async process in the action fns, they'll all get started at the same time, before any finish?
i’d say any async stuff should be done by a sender processing a mutation query expression
so coordinating that ordering would be done by the send function, which could get hairy (i think)
I'm having a lot of issues with race conditions on remote mutate functions: Basically, on the backend remote, there is a mutate function which executes an asyncronous change; but the reader gather their values before the asyncronous mutation is finished.
Lots of channels -- which is fine
The problem is that the parser function hides to the user how it is executing reads/mutates
At least with respect to call order
The other big issue is that when the parser is finally finished making its return map
It becomes a map with tons of channels
Which you can't send over the wire
So you have to go through and get the values out of the channels before you send it back to the client
matthavener: thanks. I found that om-next-demo has a remote mutation example in https://github.com/swannodette/om-next-demo/blob/master/todomvc/
synchronous remote mutate impls: https://github.com/swannodette/om-next-demo/blob/master/todomvc/src/clj/todomvc/parser.clj
yep, check out awkay’s excellent tutorial as well for some examples https://awkay.github.io/om-tutorial/#!/om_tutorial.H_Remote_Mutation
senders are also covered in the om.next wiki