Fork me on GitHub
#re-frame
<
2017-02-24
>
lgessler04:02:31

why do I need reg-cofx and inject-cofx if I already have interceptors?

lgessler04:02:54

they end up being equivalent right?

curlyfry06:02:40

@lgessler Well, inject-cofx is an interceptor (or actually returns one when you call it) that lets you add a coeffect registered with reg-cofx. All interceptors can add to the coeffects (so you are right in that they are equivalent in some sense), but using these two functions is a bit easier and more explicit. Check out https://github.com/Day8/re-frame/blob/master/docs/Coeffects.md if you haven't already.

shem09:02:15

in the docs, reading data from a server is implemented as an effect. to me it sounds more like a coeffect. i would have thought POST=effect, GET=coeffect. what is the reasoning here?

shem10:02:22

well, GET can be used to mutate state server-side, but i'm thinking of a simple read operation

kasuko15:02:26

@shem it’s not quite that way. I can see how that would seem but when you do an HTTP GET you aren’t “just reading from a server” the GET itself is a request that gets sent from your code to the server first to get the information. That request itself is a side effect from the point of view of your code.

kasuko15:02:21

any HTTP call is the same request -> result so a POST and a GET is the same side effect.

shem15:02:21

@kasuko makes sense. It also narrows down the remit of coeffects quite a bit

kasuko15:02:51

even trying to think how to implement the GET request as a coeffect I can’t even fathom. You’d have to make a synchronous call and even then I don’t know how you would specify where you call.

kasuko15:02:53

Maybe if you had like a remote config you wanted to query every time you did something, but even then that would be jumping through hoops. It’s still easier to use an effect to generate the GET request and deal with the GET’s response with a plain old event

kasuko15:02:27

which has the benefit of being asynchronous

shem15:02:48

I see the point. But it seems there are few cases for coeffects then.

kasuko16:02:11

Definitely. My favourite example is Local Storage

kasuko16:02:00

You can write a co-effect that provides the contents of the Local Storage the same way you would access the re-frame db

shem16:02:35

Where do you draw the line? Coeffects = in the browser?

kasuko16:02:00

I find it helps more to think of coeffects as inputs to your event

kasuko16:02:16

the re-frame db is an input to the event through a coeffect

kasuko16:02:01

and an effect is the output of your event.

kasuko16:02:15

but this is for “stateful” things

kasuko16:02:37

and sometimes you need both a coeffect and an effect to handle a single stateful resource

kasuko16:02:52

in re-frame there is a db coeffect and a db effect

kasuko16:02:12

the db coeffect provides the re-frame db to your event handlers

kasuko16:02:34

the db effect takes the modified db that your event handlers return and replaces the re-frame db with it.

kasuko16:02:44

That’s the beauty of the co-effects and effects. They take something inherently stateful like your app state, and remove all the “state” from most of your code, only pushing it to the far fringes (the db coeffect and effect)

kasuko16:02:00

so now your event handlers are just pure functions that take in an immutable db, and return a modified immutable db and all the icky state management is handled for you elsewhere

kasuko16:02:22

and since the db handling is all done for you by re-frame if you replace all examples above with Local Storage, then there is an example of where you would write both co-effects and effects to allow your app to read and write to Local Storage.

kasuko16:02:35

and I can see how that may be confusing if you equate a GET with reading and a POST with writing, but a GET and a POST are reading and writing for the server, not for your app.

kasuko16:02:56

aka if you write a HTTP POST in your app. Does anything mutate in your app? Not normally.

kasuko16:02:16

(other than the implied request side-effect)

shem16:02:16

From app point of view, reading from local storage and reading from server are not that different.

kasuko16:02:32

They are slightly different, enough to warrant. To read from local storage you don’t have to send an asynchronous request first. The local storage is already in your app’s memory.

kasuko16:02:54

You just get the local storage state. You don’t have to commit a side effect first

kasuko16:02:46

if you had to make a side effect change first to get the local storage then it also would implemented as an effect

kasuko16:02:52

You could make the response from the HTTP GET request available as a co-effect.

shem16:02:59

Hmm, ok. Is it atomic to request something from local storage?

kasuko16:02:47

So sending the HTTP GET would be an effect, and then reading the response could be a co-effect. However, since the response is not stateful you wouldn’t really do it that way. You can’t “change” the response.

shem16:02:41

So it's a judgment call. That's ok.

kasuko17:02:07

Everything in programming pretty much is 😜

kenny21:02:17

Is there a way to get rid of the reframe: overwriting :event handler for :foo warning messages I get when reloading? I get one for every event/fx I have registered and it is really noisy in the console. The function that is called when the app reloads is this:

(defn mount-root
  []
  (rf/clear-subscription-cache!)
  (reagent/render [views/app-start]
                  (.getElementById js/document "app")))
I am using boot-reload if it matters.

kenny21:02:40

It seems like lots of other people have this problem. Do you guys just deal with the possibly 100s of warning messages spammed to the console?

isak22:02:10

good question @kenny , i'd be curious to hear too

kenny22:02:27

It's worth noting that the warnings only occur when reloading your events.cljs file(s) but it is still very noisy and unnecessary. 🙂

isak22:02:20

yea, oddly i think this warning would only be good for prod builds

isak22:02:05

well, it works for when you do a fresh reload of the whole page in development too, i guess

kenny22:02:29

There should just be some way to disable it in your reload function.

kenny22:02:42

Yup. I just subscribed and upvoted the issue and the PR. If I have time I'll look at finishing up the PR.