Fork me on GitHub
#re-frame
<
2016-12-07
>
shaun-mahood00:12:20

@mac: If your cofx just dispatches, then it shouldn’t cause a problem with delay - but there also won’t be any data there for you to use in your handler, and if you wait for the data to come back then you’ll be taking a long time.

mac00:12:56

@shaun-mahood Yeah, the delay is an issue.

mikethompson00:12:40

@mac I haven't been following this discussion so I might be missing something but .... an HTTP post/get is an effect (not a coeffect)

mac00:12:04

@mikethompson Ok. If get from local storage is a coeffect why is a http get an effect?

mikethompson00:12:56

A good question! I guess the distinction is that Localstore is "available". In the same way that the contents of app-db is available.

mikethompson00:12:50

It is also a readonly operation. Whereas HTTP ops are often mutative (although a GET isn't)

mikethompson00:12:12

So the distinction is something around latency and readonly/write

mikethompson00:12:40

Yeah, i think it is all about time.

mac00:12:53

@mikethompson I get that read only but, but I am dealing with GET - distinguishing based on latency appears arbitrary.

mikethompson00:12:02

Within the browser, async operations are always handled "differently"

mikethompson00:12:51

But I feel your question is a really good one. I'm struggling a bit here

mikethompson00:12:40

re-frame is an event based architecture. It might need to process 5 other events in the time the GET takes to complete.

mikethompson00:12:21

Yeah, I think that is the nub of it. In the general case, during that GET, another event may occur - a websocket may deliver a packet or the user might click the "cancel" button or something. So the async nature of the GET requires different treatment to a sync call to get LocalStore data

mac00:12:45

@mikethompson That makes sense. I think the sync/async distinction is crisp.

mikethompson00:12:53

Not sure why it took me so long :-)

mac00:12:26

@mikethompson And poetically what is biting me right now, as I cannot figure out how to handle the promise returned by js/fetch 🙂

mikethompson00:12:02

Shouldn't the .then do a dispatch ?

mikethompson00:12:45

That's the equivalent of an on-success callback doing a dispatch

mac00:12:00

@shaun-mahood That was my model before which worked, but I wanted to do it cleaner and use reg-fx

mikethompson01:12:40

So, I assume you do this ...

(reg-event-fx 
   :some-id
   (fn [cofx  v] 
      {:my-fetch   {:url  "XXXXX"
                    :other   :params
                    :on-success [:fetch-worked}}))

mikethompson01:12:35

And then you need to write an effects handler to look after :my-fetch

mac01:12:48

@mikethompson Which dispatches to :fetch-worked ?

mikethompson01:12:26

sketch ...

(reg-fx 
   :my-fetch 
   (fn [fetch] 
       (-> (js/fetch  (:url fetch))
           (.then  #(dispatch  (conj (:on-success fetch) %))))

mac01:12:07

@mikethompson Yeah, I think I got the idea. Thanks.

shaun-mahood01:12:27

One thing I find interesting about that approach is that it really does set up a different way to think about the 3 of them - coeffects exist at the time of the event (sync), events do things with data that exists (sync), effects set up future data for either of the others (async). I’ve not thought about it that specifically before, and it does help fill in the mental model a bit more for me.

mikethompson03:12:56

That 1 is a typo

cmal03:12:13

ok, thanks simple_smile

mikethompson03:12:29

Seems to have already been fixed in develop

mikethompson03:12:40

Will roll through to master shortly

gphilipp08:12:33

I’ve posted a question regarding core.aync in re-frame handlers at https://github.com/crisptrutski/matchbox/issues/42#issuecomment-265376053. Have anybody faced this issue ?

mf09:12:03

@mikethompson Good to know that the upgrade to 0.8 is relatively painless... I'm onto it today!

jiangts21:12:22

Hi all, have a conceptual question: in OOP we have inheritance. Hence, if I had 1 undoable TodoMVC class, I could trivially extend it and include a separate, customized instance on the screen. How is this done in re-frame? I understand that we dislike hidden state in objects and we prefer composition, but how do we compose behavior in reframe? Also if we duplicate the same TodoMVC instance in reframe the data will be synchronized across both which isn't what I'm trying to do

jiangts21:12:31

To me, it seems subscriptions and event dispatches on the component need to be localized to that particular instance. Or something.

mikethompson22:12:21

@jiangts The behavior stays the same - which is to say the event handlers and subscriptions are the same across "instances" of TodoList. It is just that your subscriptions and event handlers are now paramaterised by the instance id (path into app-db?) they should be dealing with. This is not dissimilar to how you might create a PostgreSQL database which contained multiple todo lists - you'd create (relational) structures to seperate the todolist instances. app-db isn't relational but you'll create structures within it (different paths?) to seperate out the N TodoList instances and then your subscriptions and event handlers would be given data (path?) about which instance they were dealing with.

mikethompson22:12:17

So the key takeaway is: in OOP you deal with "instances" of things. Your hand around the instance by reference. In re-frame (and a relational database) you tend to think more in terms of "the id" of things and work with that - path or foreign key. So, if a subscription had to deliver a particular item in a particular TodoList, you would give it the two ids (of the todolist, and the item).

mikethompson22:12:27

Data oriented, not Object Oriented

mikethompson22:12:37

id vs direct reference to an instance

jiangts22:12:48

that makes sense. so it seems to write re-useable components it's a good idea to have all the events and subscriptions also pass their own id.

jiangts22:12:08

and also to establish some notion of id's for components

jiangts22:12:25

hmm, and then if i wanted to reuse a component in a different project, i'd have to find all subscriptions and event handlers for a particular component, as well as the component itself, and port it over? and make sure it works out with a new db?

jiangts22:12:56

in this case is it worthwhile to co-locate the subscription handlers and event handlers, their fx/cofx, and the component all in the same file?

mikethompson22:12:50

If you have a reusable component then I'd put all details for it within its own directory

mikethompson22:12:10

So that directory would have a subs.cljs and an events.cljs etc

mikethompson22:12:30

That would be my version of colocation

jiangts22:12:53

aha. thanks! definitely appreciate data oriented vs. object oriented, but a lot of patterns it seems need to be re worked out 🙂. and i'm guessing to "extend" a component I could switch on an id to run a modified handler or something.

mikethompson22:12:01

Yeah, I'm not sure I have a good way of "extending" ... somehow we don't seem to do that much

jiangts22:12:06

yeah, I haven't done it much in re-frame either. I'm having all these thoughts cause I was watching a friend of mine code a huge Ext.JS app, which is heavily Object Oriented. He was extending all these fancy components and it was indeed a powerful concept, so I was wondering how it translated.