om

Please ask the channel first, not @dnolen directly!
2017-05-29T00:09:03.360966Z

oh yea, hey!

2017-05-29T00:09:09.361376Z

i just put tried this out

2017-05-29T00:09:19.361997Z

(defui CanvasExample
       Object
       (componentDidMount [this]
                          (let [canvas (aget this "canvas")
                                ctx (.getContext canvas "2d")
                                _ (aset this "ctx" ctx)]
                            (aset ctx "fillStyle" "green")
                            (-> ctx
                                (.fillRect 10 10 100 100))))
  (render [this]
    (dom/canvas #js {:ref (assign-ref this "canvas")})))

sophiago 2017-05-29T00:10:57.368256Z

oh so you did actually mean calling the componentDidMount directly

2017-05-29T00:12:04.372690Z

yep, it's all just react at the end of the day πŸ™‚

2017-05-29T00:12:12.373177Z

om really only changes how data is managed

sophiago 2017-05-29T00:12:33.374599Z

the issue, though, is i'm using a typical factory pattern and just updating a global map. so currently i have a function like:

(defn new-canvas [id width height]
  (let [str-id (str id)
        key-id (keyword id)]
    (swap! store assoc key-id
           {:id str-id, :width width, :height height})
    (swap! store assoc-in [key-id :ctx]
           (.getContext
            (.getElementById js/document (str id)) "2d"))
    id))

sophiago 2017-05-29T00:13:47.379201Z

it seems to be creating a race condition (again, not totally sure when the reconciler triggers rerenders) where the canvas hasn't been rendered for me to pull the ctx

2017-05-29T00:14:29.381967Z

i see, yea this is outside of react's model

sophiago 2017-05-29T00:14:43.382881Z

actually, i suppose i could just modify the original defui to pull the context in componentDidMount and add it to my global map. that seems much cleaner

2017-05-29T00:15:03.384169Z

was about to say the same πŸ™‚

2017-05-29T00:15:36.386293Z

i just store the ctx on the component itself, but for sure you can add it into the store as well

2017-05-29T00:16:37.390119Z

i often use this helper for setting the ref btw

sophiago 2017-05-29T00:16:39.390206Z

yeah, i'd need to have it in the store since i'm drawing from outside the component itself

2017-05-29T00:16:42.390391Z

(defn assign-ref [this ref]
  (fn [el]
    (aset this ref el)))

2017-05-29T00:17:04.391711Z

you used to be able to pass a string but now the recommendation is to use a callback,

sophiago 2017-05-29T00:17:41.393962Z

i'm a bit confused by this. both the purpose and what aset does in cljs

2017-05-29T00:17:41.394009Z

cool, that makes sense

2017-05-29T00:18:18.396208Z

https://github.com/binaryage/cljs-oops

2017-05-29T00:18:34.397048Z

the oops readme has a good explanation

2017-05-29T00:19:49.401594Z

and the cheatsheet- http://cljs.info/cheatsheet/

sophiago 2017-05-29T00:20:06.402640Z

ok, so this is just a way to cut down on the js boilerplate when you need to set a var to a ref queried from the dom?

sophiago 2017-05-29T00:20:22.403653Z

oh wow i had no idea there was a cljs specific cheatsheet πŸ™‚

2017-05-29T00:20:37.404508Z

yea, i use it in plain js too

2017-05-29T00:20:52.405333Z

haha yea, i keep finding things scattered about the net

sophiago 2017-05-29T00:20:52.405358Z

it's still odd to me why you'd need a js array

2017-05-29T00:22:06.409884Z

it's poorly named, because JS arrays are really objects anyway, you can use aset for objects

2017-05-29T00:22:19.410641Z

it will compile to obj["prop"] = val

sophiago 2017-05-29T00:22:35.411778Z

ah true. it's been a while since i've written plain js (thankfully)

2017-05-29T00:22:56.412904Z

hah

sophiago 2017-05-29T00:25:59.425229Z

well, thanks for the tips! i may have to wait to try them out...this is all on another branch of this project i realized afterwards i could maybe debug without using multiple canvases and just one hardcoded one. not sure which i'll end up using

2017-05-29T00:32:43.452736Z

cool, no problem and good luck!

πŸ‘ 1
sophiago 2017-05-29T02:13:22.947349Z

hey, just hoping for a sanity check on modifying your code to store the context in the map (similar to how the keys are initialized, rather than directly with swap!):

(defui canvas
  Object
  (render [this]
          (let [{:keys [id width height]} (om/props this)]
            (dom/input #js
                       {:id id
                        :width width
                        :height height
                        })))
  (componentDidMount [this]
                     (let [canvas (aget this id)
                           ctx (.getContext canvas "2d")
                           {:ctx ctx} (om/props this)])))

pasi 2017-05-29T10:18:14.008231Z

hey. Just getting started with Om/Om.next. Couple quick(?) questions. First, I've read some Clojure guides and I have a (very) basic grasp of Clojure syntax now. Is there anything I should really know before diving into Om/Om,next language syntax/features wise? Second, I looked at some Om(next) docs yesterday and a lot of them had "under heavy development warnings". I guess they're still the docs I should be reading? Third, "Note: this tutorial is for Om, not Om Next" - I assume learning Om carries over to Om next and the "basic tutorial" at https://github.com/omcljs/om/wiki/Basic-Tutorial is still somewhat valid?

2017-05-29T10:40:09.235411Z

@pasi There isn't much carry over from om to om.next, you should start with the om next quick start.

jimmy 2017-05-29T11:08:36.518773Z

@pasi If you are new to Clojure, I recommend you to start with some thing like Rum, Reagent and Reframe first if you want to build something. Otherwise, if you are learning, just go with Om.next directly.

pasi 2017-05-29T11:12:32.557036Z

I use React, Redux & co based stack at work quite extensively so I'm particularly interested in Om Next. Broadening my horizons etc.

2017-05-29T11:14:29.576045Z

@nxqd Why do you recommend those first?

jimmy 2017-05-29T11:17:19.603685Z

@danielstockton It's based on my experience, I find it's easier for Clojurescript newbie to try out with those framework first since they are easier to work with, and you can build a prototype easily. It's not the same for Om.next. If they are experienced, then they are free to choose πŸ™‚

claudiu 2017-05-29T11:18:06.611177Z

@pasi I’m also switching from react, redux. Om-next has quite the learning curve unfortunately. I found rum & reframe a lot easier. There is also untangled (om-next framework).

claudiu 2017-05-29T11:21:02.639299Z

I found tony kay’s videos really helpful most of the stuff applies to om-next https://www.youtube.com/playlist?list=PLVi9lDx-4C_T_gsmBQ_2gztvk6h_Usw6R

2017-05-29T11:22:53.657333Z

Fair enough, it seems to be a common viewpoint. I've looked at re-frame/reagent very briefly but didn't really grasp it any easier than om.

claudiu 2017-05-29T11:28:20.709597Z

imho the docs and examples are better. For om next I think that the documentation and examples don’t really explain the overview that well. Spent a lot of time re-reading and trying to get my head around them.

claudiu 2017-05-29T11:30:00.726240Z

Would have really loved to see something like https://github.com/kriasoft/react-starter-kit for om-next. There is a live version here https://demo.reactstarter.com/

2017-05-29T11:32:03.747454Z

I think I was sold on the philosophy of om.next (dnolen talks etc...) before I actually knew anything about it. It seemed like how we should be building UIs. With reagent/re-frame (and incidentally boot vs lein), I see lots of blog posts, documentation, people telling me to use them, but never really heard a convincing argument other than that (to motivate me to dive deeper).

2017-05-29T11:34:31.771376Z

I was similarly sold on Clojure at the beginning, on abstract ideas rather than 'well everyone else is using X'

2017-05-29T11:37:38.801720Z

I think if I had gone by number of blog posts and documentation, I would still be writing ruby.

πŸ‘ 1
claudiu 2017-05-29T11:38:03.805731Z

:))

claudiu 2017-05-29T11:39:39.821358Z

It’s just hard to get a working template. πŸ™‚ Personally can’t turn back because the end result is just so much cleaner πŸ™‚

pasi 2017-05-29T11:48:36.911325Z

I actually made some mental notes about the sort of things I'd like to see in Om next documentation

pasi 2017-05-29T11:52:00.946Z

it's kinda hard to objectively identify pain points when you're not super comfortable with the syntax itself. I think React docs are a great example of well-written, informative docs but I've never read them not knowing JS quite well.

pasi 2017-05-29T12:03:50.073527Z

in the spirit of trying to actually give some useful feedback.. some of the docs are bit heavy on jargon and occasionally I felt like some extra info would be great. I'm talking about https://github.com/omcljs/om/wiki/Quick-Start-(om.next) specifically here: >"The reconciler accepts novelty". Novelty? What? A quick explanation of what novelty means here would help a lot. The routing section is okay content wise but a lot of "web app people" probably associate "routing" with views, rather than client-server side information transfer. Parsing & query expressions chapter could maybe provide a little more context and quickly gets quite technical. I guess explaining what "parsing" means in the context of client-server architecture would help. Also little more time could maybe be spent on explaining query expressions.

claudiu 2017-05-29T12:06:59.107696Z

@pasi also, for getting started I found the Overview of Om Next and om tutorial most helpful. First link from community resources https://github.com/omcljs/om/wiki

2017-05-29T12:08:28.123744Z

@pasi I think routing is used in the usual context in the docs i.e. switching views.

pasi 2017-05-29T12:11:32.157149Z

I should add that so far I really like the ideology of Om next and at the very least, I hope I can take some of its thinking back to JS world.

jimmy 2017-05-29T12:55:23.664747Z

@danielstockton Don't get me wrong, om.next is really good. I have worked with 3 frameworks. Just to make sure if he/she is a newcomer, they can start with those 3 frameworks then go further exploring om.next. It would be more encouraging.

adamvh 2017-05-29T15:10:49.391303Z

@pasi you may want to look at untangled-web

adamvh 2017-05-29T15:11:00.393379Z

which is a framework built on top of om next

adamvh 2017-05-29T15:13:53.427496Z

om next itself is powerful and flexible, but also somewhat bare-bones. untangled makes some opinionated choices to make the "getting started" process easier, and, as a bonus, there's a sweet dev guide that you clone that comes with a bunch of live-reloading examples

pedroteixeira 2017-05-29T22:47:14.714660Z

pasi: some useful information here too https://www.martinklepsch.org/posts/om-next-reading-list.html

pedroteixeira 2017-05-29T22:48:54.722145Z

anyone know if is https://github.com/arohner/om-html the "current way" to use hiccup like sintax with om.next? or is there a better alternative? I had to patch this one to work with latest clojure spec.alpha

fz 2017-05-29T23:25:36.889588Z

Is it safe to directly invoke the :action of a mutation function from another to "chain" mutations? Is this the best/recommended way to chain mutations?

(defmethod mutate 'bar [_ _ _] {:action (fn [] …)})
(defmethod mutate 'foo [_ _ _] (((mutate 'bar '_ '_ '_) :action)))

anmonteiro 2017-05-29T23:41:15.959273Z

@fz can’t you (om/transact! this [(foo) (bar)]) ?

fz 2017-05-29T23:54:52.018960Z

I don't think so … in this case, this is being used as an Untangled post-mutation, which AFAIK only allows a single symbol. Happy to ask in #untangled if this question is more specific to that …