Clojurians
# om

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

tobiash 13:03:24

is there a way to pass through IQuery and IQueryParams? I'd like to write a higher-order-component to re-use some functionality

anmonteiro 13:23:38

@tobiash you can write "pure" components without queries

anmonteiro 13:23:44

not sure if it's what you're looking for

tobiash 13:24:47

i want to refactor code that subscribes to events in componentDidMount and then unsubscribes accordingly in componentWillUnmount

tobiash 13:27:42

mh, ok instead of wrapping the "higher-order component" around my component, i could wrap my child components with it. But I think hoc is a nice pattern

tobiash 13:34:01

maybe that would be a nice addition to om.next?

tobiash 14:31:56

it might be that I'm looking at these things too much from a React perspective, but I keep running into these issues: I have navigation bar that also displays some action buttons, depending on the current route. How do get the button presses to the current route? Currently I use a core.async channel, but that means that every route component has to subscribe/unsubscribe to it

tobiash 14:32:47

maybe it would be nicer if the route component implemented some protocol to receive the events and then I would not need the sub/unsub boilerplate

nha 16:19:29

I am trying to make server-side rendering in om,next, and have an exception creating the server reconciler, if someone has a clue: http://stackoverflow.com/q/41082153/1327651

anmonteiro 16:35:49

@nha that's because stuff in the reconciler has circular references to it

nha 16:39:21

Oh ok - but can I work around it?

anmonteiro 16:39:56

yeah, with remove-method and prefer-method

anmonteiro 16:40:05

the problem is just about the printing

nha 16:41:05

I am trying something like that right now: (prefer-method print-method om.next.Reconciler clojure.lang.IRecord) (does not work - never used prefer-method before)

nha 16:42:31

(prefer-method print-method om.next.Reconciler clojure.lang.IDeref) does not throw, but then does not seem to change anything

nha 16:44:14

Anyway, since this only printing putting it in a var is fine.

nha 17:03:09

So far I tried:
(prefer-method print-method om.next.Reconciler clojure.lang.IRecord) (prefer-method print-method om.next.Reconciler clojure.lang.IDeref) (prefer-method print-method rethinkdb.core.Connection clojure.lang.IPersistentMap) (defmethod print-method om.next.Reconciler [r writer] (print-method {:config (:config r) :state (:state r)} writer)) but none of these seem to work

nha 17:03:46

Am I barking at the wrong tree?

anmonteiro 17:04:15

I've gotten that to work before, but I don't quite remember how

anmonteiro 17:04:29

I remember also using remove-method

nha 17:05:51

I'll try that, thanks

nha 18:05:10

Ok that will be for another day.

How can I render-to-str a CompassusApplication. (in clojure)?

anmonteiro 18:05:39

@nha hrm, I don't think I've ever tried it :slightly_smiling_face:

anmonteiro 18:05:48

but you should be able to compassus.core/mount!

anmonteiro 18:05:52

with a nil target

anmonteiro 18:06:05

then pass the return of that to render-to-str

nha 18:06:16

Thanks, will try :slightly_smiling_face:

anmonteiro 18:06:45

@nha PR welcome adding a test for it, even if it works

anmonteiro 18:06:57

the Compassus tests run in Clojure too

nha 18:07:17

yes I saw that - hence I assumed it worked server-side as well

nha 18:07:50

hmm it seems to throw (compassus/mount! app nil):
Unhandled java.lang.ClassCastException clojure.lang.PersistentHashMap cannot be cast to java.io.PushbackReader

anmonteiro 18:09:02

@nha the whole stacktrace would be more helpful

nha 18:09:48

@nha uploaded a file: stacktrace and commented: Right :slightly_smiling_face:

anmonteiro 18:12:00

hrm weird

anmonteiro 18:13:15

looks like either:
1) a problem with your parser function
2) a bug in Compassus :slightly_smiling_face:

nha 18:14:03

could be my parser to be honest

nha 18:14:20

migrating from cljs to cljc - I may have things lying around

nha 18:14:34

I'll try doing that in the compassus repo

anmonteiro 18:14:45

right, there are a few hurdles you may have to go through

anmonteiro 18:14:57

in any case, I'm happy to know you're using Compassus!

nha 18:15:59

Well I'm just experimenting :slightly_smiling_face:

nha 18:16:29

(I am not sure I understand the different tradeoffs of the different routing approaches)

anmonteiro 18:16:50

Compassus is just a library around the union query approach

nha 18:16:52

But yes I am trying to get server-side + compassus + bidi althogether

anmonteiro 18:17:00

not much else there tbqh

nha 18:17:34

Yes I saw that. previously I had a transact! in a key :app/route. looks similar

nha 18:18:49

Something like that:
(componentDidUpdate [this _ _] "Sync state -> url" (let [{:keys [current-route]} (om/props this)] (when (not= current-route (url->route js/location.pathname)) (pushy/set-token! history (route->url current-route))))) (componentDidMount [this] "Sync url -> state" (let [listener (pushy/pushy #(om/transact! this `[(route/update {:value ~%}) :route]) url->route)] (pushy/start! listener) (set! history listener))) (componentWillUnmount [_] (pushy/stop! history)) I made it work but now completely sure how now to be honest :confused:

nha 18:21:40

By the way, I see you do not use componentDidUpdate in the bidi mixin?

anmonteiro 18:22:41

@nha it's just a simplistic example

anmonteiro 18:22:46

up to you to implement it if you want

anmonteiro 18:23:05

there's actually no will-update mixin

anmonteiro 18:23:14

so PR welcome for that and did-update!

nha 18:23:24

aha ok :slightly_smiling_face:

atdixon 19:36:50

re: om/next, i have multiple components (to be added via add-root!), all contending to read/mutate the same application state atom (and reading & updating the same keys therein). if I use the same reconciler for all components i seem to get errors like "no queries exist for XComponent", etc. is the correct thing to do to create separate reconciler for each component? that doesn't seem right, though. i want component X to modify, say, :some-data, and have Y update as necessary in response. i would think a singular reconciler would need to orchestrate that? what am i missing?

drcode 22:35:51

@atdixon No, one reconciler should work fine. You are probably not following the 3 golden rules of OmNext queries:

  1. There must be at least one query key for every component (you can't just say "the parent and this child both use the :foo query endpoint"- Each component needs its own endpoints in the query tree)
  2. The query for a parent must call om/get-query on all children to populate its own query
  3. The render function in the parent must pass props to the children in exactly the same manner as described in the parent query.
drcode 22:40:11

In the past, when I was breaking these rules, I got the "no queries exist of XComponent" error.

atdixon 23:24:29

Thx for the reply @drcode -- I believe I'm following those rules. my problem seems to stem from trying to add seperate roots (add-root!) but sharing the same reconciler and state. Can I have more than one root for the same state? For the same reconciler?

drcode 23:27:34

Oh you got me there, didn't realize you have multiple roots... I don't have any insight into that use case...