Fork me on GitHub
#om
<
2016-07-11
>
Oliver George11:07:45

Hello. Is it possible to mix om next in with an existing app. Something which might facilitate a gradual migration from a cursor based "om previous" approach.

anmonteiro13:07:48

@wilkerlucio: hah! solved your issue

anmonteiro13:07:01

so you need to (set! (. c -om$isComponent) false) instead of gobj/set

anmonteiro13:07:13

everything should work then

anmonteiro13:07:20

tested under advanced

wilkerlucio14:07:27

@anmonteiro: thank you very much, that works 🙂

anmonteiro14:07:14

@wilkerlucio: I didn’t check if you have to clone prototype or not though

anmonteiro14:07:18

you might want to check that

anmonteiro14:07:37

since prototype lookups are dynamic, you might be changing every prototype

wilkerlucio14:07:24

I think that's not the case, because we are not changing the prototype there, just adding the om$isComponent to the object itself, not the prototype

wilkerlucio14:07:46

but I got into a situation here were Om did tried to apply the hack a second time, and it failed

wilkerlucio14:07:28

on my case, I check if the object implements my custom static method, otherwise I call the default get-query, doing that on the hacked instance fails (that same previous problem, try to get the prototype where there isn't one)

wilkerlucio14:07:23

my code ended up like this:

wilkerlucio14:07:25

(let [comp' (r/route->component route)
      comp (js/Object.create (.-prototype comp'))
      _ (set! (.-om$isComponent comp) false)
      comp (if (implements? r/IRouteMiddleware comp)
             comp
             comp')])

anmonteiro14:07:18

@wilkerlucio: so that works, yeah?

wilkerlucio14:07:27

yes it does 🙂

anmonteiro14:07:07

still weird that advanced compilation elides static methods

dnolen14:07:08

@anmonteiro: yeah it’s weird, I wonder if there’s way to prevent that via some Closure thing

anmonteiro14:07:49

@dnolen: yeah I’d be interested in that, I’ll try to look it up in my spare time but I don’t have a lot of Closure experience

anmonteiro14:07:06

could you also shed some light on set! vs goog.object/set in advanced compilation?

dnolen14:07:19

goog.object/set is only for dealing with Object treated as maps

dnolen14:07:57

dynamic string keys

dnolen14:07:31

set! works for setting static properties known to Closure under all compilation modes including advanced

anmonteiro14:07:43

@dnolen: so for JS instances it’s no problem to use set! and (.-prop obj) ?

dnolen14:07:54

yes that’s fine

anmonteiro14:07:07

gotcha, thanks

wilkerlucio14:07:08

@dnolen: I still not clear on the distinction between gobj/set vs set!, do you know why the set! worked while gobj/set didn't on this case?

dnolen14:07:58

dynamic string keys don’t get munged

dnolen14:07:05

Closure doesn’t consider them

wilkerlucio15:07:03

ah, got it, since the om$isComponent is going to get munged, the set calls needs to use the munged name, thanks

hlolli15:07:36

Shouldn't a component that is defined with (defui Mycomp .. return true for (om/component? Mycomp) or am I misunderstanding something?

anmonteiro15:07:52

@hlolli: om/component? checks if it’s an instance

anmonteiro15:07:03

it will return false for component classes

hlolli15:07:40

ok, was trying to do om/update-state! outside defui macro. So insead of using this like I always do, I was just checking if I could pass in the component name and mutate the component local state that way. Probably a bad idea.

anmonteiro15:07:49

@hlolli: definitely a bad idea because local state is specific to instances and there could be several instances of the same class

hlolli15:07:01

yes, when you say it, I see how ill tought this is. I will rather have a function return a value that I update in that instance. So its just me experimenting in the wrong direction. Thanks for pointing this out.

hlolli15:07:33

@anmonteiro: Happy celebrations on protugal btw :flag-pt:

anmonteiro15:07:34

Thanks, I suppose. I like watching the matches but I don’t go crazy about celebrating 🙂

wilkerlucio17:07:21

when using the wildcard selector [*], given the join doesn't exists (blank data there), Om.next is returning the full database (as I was querying [*] on root), is this the intended behaviour? I was expecting it to return nil

calvis19:07:49

question about having two different remotes such as (A) authentication and (B) something that does remote computation only when we’re authenticated I’d like to be able to “trigger” the running of (A) when (B) gets a 403 response by returning some novelty like {:authorized? false} which on read would do {:authentication true} to run (A) — but I notice the parser doesn’t care enough to rerun the read for the :authentication remote after the novelty for (B) is merged in so authentication never happens 1) is this not the "right way" to do it, and if so 2) is there an example online of a more om.nexty way to do it

cmcfarlen19:07:55

@calvis It might be easier to have auth handled separately, but you might be able to trigger the remote read by transacting on the reconciler when you get the 403 and include some key that will respond to the :authentication remote.

calvis19:07:45

so (B) would have to know about the reconciler? that’s not a piece of information I thread through right now

cmcfarlen19:07:49

Not, (B), but perhaps your sender fn that gets the 403?

calvis19:07:18

oh sorry I was conflating the two - the function responsible for calling the (B) remote would have to know about the reconciler

cmcfarlen19:07:02

yeah, that might a trouble. My sender fns don't know the reconciler either.

calvis19:07:30

I did something similar by passing the channel for calling (A) to (B)’s sender fn but that felt a little out-of-band to me

cmcfarlen19:07:09

I think I might try to merge some info in that would be read locally by a component and then in the componentWillReceiveProps react lifecycle, check for the need to reauth

calvis19:07:13

so I’m not going to get any help from om.next here? this seems like a pretty normal thing to want to do

cmcfarlen19:07:52

So the response from (B) when merged by the sender cb would introduce novelty that would be read by some component and when it sees :authorized? change to false would just transact! so the :authenticion remote would be used.

cmcfarlen20:07:05

Authentication seems like a remote mutation type thing, not really a read thing. So if you want to use the reconciler to perform that you might have to get some feedback first and then do a (om/transact! comp-or-reconciler '[(auth/login {})]) or something

cmcfarlen20:07:56

For my app authentication is part of the startup, and not part of om

anmonteiro20:07:53

@calvis: I think it should be easy enough to do that by overriding :merge in the reconciler

anmonteiro20:07:45

your custom merge function would: 1. call om/default-merge for the default behavior 2. queue the keys you want for re-reading which would then trigger reads in the parser

calvis20:07:37

so the keys are being reread, but only for their :values and not for the remotes, is that possible to trigger via merge? “pls read for all remotes as well”?

anmonteiro20:07:47

@calvis: ah right, makes sense they are being re-read only locally (as a post-remoting hook).

calvis20:07:05

yeah, it seemed like a reasonable thing to not reread the remotes after

anmonteiro20:07:17

you can call om/gather-sends in that custom merge function

anmonteiro20:07:11

not sure if that would be exactly what you want, but it takes a vector of remotes as the 3rd argument, which gives you more control over which remotes to gather the sends for

anmonteiro20:07:35

i.e. you probably don’t want to read remote stuff from B since it’s what gave you the response already

calvis20:07:46

yeah, basically give it special permission to re-run (A)

anmonteiro20:07:07

I don’t think there’s any docs on gather-sends but it’s part of the public API

anmonteiro20:07:49

@calvis: you’ll also need to call schedule-sends! after calling gather-sends

calvis20:07:34

okay, seems reasonable

calvis20:07:00

it would be nice to have a way to just say “re-run all the remotes afterwards”, since that is the behavior I want in all cases with this app

anmonteiro20:07:34

@calvis: you can probably do that by overriding merge, as I suggested

anmonteiro20:07:44

it’s why Om Next provides these extensions in the reconciler

anmonteiro20:07:19

that said, baking all these use cases into Om Next by default is out of the scope of what Om Next is aiming to be IMHO

anmonteiro20:07:57

Om Next's focus is on providing these building blocks which you can assemble into a more full-fledged application

calvis20:07:03

that’s true, maybe it was just a documentation failing then in my case, I was kind of expecting everything to get rerun because nothing mentioned reads getting called multiple times once for each remote

anmonteiro20:07:05

it’s also what allows things like Untangled to exist

anmonteiro20:07:22

I haven’t used it myself but I’ve heard good things

anmonteiro20:07:30

if you haven’t heard about it: http://github.com/untangled-web

calvis20:07:39

yes I’ve heard thanks

anmonteiro20:07:36

WRT documentation, it definitely needs to be improved. it’s also why Om Next is still alpha

calvis20:07:30

yeah we knew that when we started hahah

dnolen21:07:12

cut 1.0.0-alpha40 with the latest fixes / enhancements

takeoutweight21:07:50

question: Is it considered in-spec for a mutate handler to transact! a new transaction when it's handling an existing transaction? Or should the transactions represent distinct & isolated user intents as much as possible?

anmonteiro21:07:26

@takeoutweight: I wouldn’t recommend doing that

anmonteiro21:07:03

you can always do things like: (om/transact! ‘[(some/action!) (other/action!)])

dnolen21:07:11

yes, calling transact! from within a mutation is not recommended

takeoutweight21:07:25

Makes sense. In our experiment the use case was having the second transaction conditionally depend on data computed when handling the first so issuing both transactions in the same transact! wasn't quite right. But it sounds like keeping the UI logic factored in a a way that all the cascading operations can be kicked off by a single transaction would be the way to go.

dnolen21:07:30

@takeoutweight: for better or worse om.next is designed around a distaste for chain reactions

danburton22:07:31

Is it normal to call om/set-query! from within a transaction, or would you recommend that this be called directly next to (rather than triggered by) om/transact! instead?

dnolen22:07:09

@danburton: would not do that in a mutation, I would do it next to

dnolen22:07:42

rule of thumb - don’t nest any top level mutation calls