Fork me on GitHub
#re-frame
<
2020-10-15
>
macrobartfast00:10:59

I just posted a lein re-frame template based question to #clojurescript if anyone has a moment to look at it.

furiel14:10:11

Can someone help me with re-frisk ? I am learning re-frame and re-frisk helped me a lot during app development. There is this call: (re-frisk/enable) which puts the debug window into my application. Which I do not want to add in the production version, only for the development. Probably I need to add an if around enable, but I am not sure what should be the condition. Just guessing here: I have a figwheel.main based leiningen project: I have dev.cljs.edn and I can probably create a prod.cljs.edn too, which could carry build information. But me seems these are intended for figwheel.main, and I am not sure their content is available directly in my application. Is there any easy way to make (re-frisk/enable) conditional without creating a separate configuration file and read it's content?

p-himik14:10:34

Check out re-frame.interop/debug-enabled?.

furiel14:10:42

Thank you for the idea! I am not entirely sure how this works, but according to the comment in the source code: the idea is that it defaults to true, but if I used advanced optimization, this will somehow turn to false automatically. Neat! I try this out.

furiel15:10:21

No I misunderstood. I somehow need to set goog.DEBUG in the leiningen project file.

andre19:10:39

it's better to use :preloads [re-frisk.preload] in your dev config

furiel19:10:27

@U0CC9TJ11 Thank you! Preload worked nicely.

Oliver George22:10:02

The rise of asynchronous apis is a point of friction for re-frame. Possibly an inherant conflict of "state in memory" vs "state accessed via async".

Oliver George22:10:14

Some kind of Promise friendly cofx might help. On react native the sqlite database and keystore apis are fast but promise based.

Oliver George22:10:49

Reminds me of subs: signal + compute fns.

p-himik22:10:43

It's still possible to use things that re-frame offers in an async environment. But it will definitely have some boilerplate. But I'm not sure what you mean by "state accessed via async".

Oliver George22:10:59

Perhaps "data sources" is a better word than "state" since that tends to imply the app-db in re-frame.

Oliver George22:10:33

I agree it's possible... but if you're doing it in event handlers you're moving towards a more verbose version of the origial JS "callback hell". One option is to bundle things up as fx handlers. Another is the async-fx lib (sometimes).

Oliver George22:10:18

I think cofx returning a promise and delays event execution until it resolves is an interesting idea.

p-himik22:10:05

I understand the concept but I struggle to come up with an actual use case for that.

Oliver George22:10:56

(Quick aside: I love your engagement on slack. You do good work)

💯 3
p-himik22:10:12

Heh, thanks. :)

Oliver George22:10:12

Some examples I'm looking at right now. It's a React Natvie app.

Oliver George22:10:41

I'm storing an api token in keystore. That means to use the token I need to pull it out via an async api.

Oliver George22:10:11

So to avoid this in every handler which needs it I have choices 1. put it in app-db (keep in memory) 2. make all api calls reach into keystore directly (promise chain) 3. register two handlers the first to request data, the second to process

Oliver George22:10:19

I went with option 1

Oliver George22:10:21

Another example

Oliver George22:10:33

I have an app with a database too large to hold in memory.

Oliver George22:10:41

It's in sqlite which has an async api

Oliver George22:10:57

to pull data out needed for a view I need to make one or more queries

Oliver George22:10:36

So you need multiple handlers and perhaps an fx which to prepares data

Oliver George22:10:51

That moves more logic into fx which makes them more complex.

Oliver George22:10:55

that sort of thing.

p-himik22:10:45

Right, it makes it more clear, thanks.

p-himik22:10:42

Actually, I just started to remember how at the very beginning of my path with re-frame I was reading about IndexedDB and I couldn't quite reconcile the two things in my mind.

Oliver George23:10:36

I think there's a argument that we have the necessary building blocks and that the convenience of chaining promises comes at the price of being more complicated (complected) and thus more difficult to test and reason about.

Oliver George23:10:53

Still think it'd be nice if re-frame was "closer" to data sources.

p-himik23:10:23

Chaining promises is one thing. Using a plain promise as a data source is another. I would argue that the latter is acceptable.

Oliver George23:10:44

yep. that would cover the common case.

lilactown06:10:28

I'm a bit more ornery in that I believe that just events are too low-level for app building

lilactown06:10:29

re-frame's event system is nice from a perspective of purity, but IMO an event system should be something we strive to build higher-level abstractions on top of

lilactown07:10:56

unfortunately, re-frame's API, docs and general guidance encourage developers to use re-frame events as the language they use to implement their app, which makes common things like accessing a piece of data asynchronously tedious and error prone

lilactown07:10:12

promises are wonderful abstractions for a huge amount of use cases; they are composable (events: must build your own composition), they are completable and failable (events: must build your own completion and failure mechanisms), and have an identity (events: must build your own way of identifying between different occurrences)

lilactown07:10:38

unfortunately they lack cancellation, which events can get you... if you build it and all of the other things 😄

p-himik07:10:19

Absolutely agree.

Oliver George07:10:14

Anything jump out as examples we can learn from?

p-himik07:10:55

I've seem a few FSM libraries built [with support]for re-frame. Or just libraries that remove the need for some boilerplate. This one just yesterday: https://lucywang000.github.io/clj-statecharts/docs/integration/re-frame/ Others: - https://github.com/ingesolvoll/re-chain - https://github.com/Guaranteed-Rate/re-flow There was another one but I didn't save it - I remember not liking it because it heavily relied on side-effects in event handlers. Should've still saved it though. But I haven't used any of them yet.

victorb10:10:58

statecharts is an area I think we're still trying to find the right approach with, with regards to what level the APIs should act on. Definitely warrants more exploring though. Some more libs with statecharts+re-frame: • https://github.com/MaximGB/re-statehttps://github.com/jiangts/re-state And finally, re-frame EP about general state machines, seems @U051MTYAB is leaning towards behavior trees instead of statecharts though, at least from what I gathered from a podcast he was in, talking about re-frame: https://github.com/day8/re-frame/blob/master/docs/EPs/005-StateMachines.md

victorb10:10:41

also, good general introduction to statecharts and how they can be beneficial: https://statecharts.github.io/

p-himik11:10:08

Thanks for the links. Also, not sure if it's the same lib I was talking about but MaximGB/re-state definitely does dirty things.

p-himik11:10:28

But maybe it's practicality vs purity in this case, not sure.

victorb11:10:05

yeah, guess it's the same trade-off that re-frame is doing with the registers (or is it registrar?) where there is just one global one for practicalities sake. There is a doc in the re-frame repo somewhere talking about this but not finding it atm