Fork me on GitHub
#re-frame
<
2017-12-11
>
joelsanchez10:12:34

I don't want to get the value of a subscription from an event. I want to build a subscription from a coeffect different from db. I don't see the relation.

joelsanchez10:12:17

So, I want this (not possible right now):

(rf/reg-sub
 ::open?
 [(rf/inject-cofx :local-storage)]
 (fn [{:keys [local-storage]}]
   (get local-storage ::open?)))

joelsanchez10:12:48

Because that is not possible, I am forced to keep local-storage saved somewhere in the db, and do this:

(rf/reg-sub
 ::open?
 (fn [db]
   (get-in db [:local-storage ::open?])))

joelsanchez10:12:42

It's not big deal but it is weird that subscriptions can't have coeffects, in a similar way to events. But my question is not about events.

joelsanchez10:12:20

One possible solution (albeit hackish) is to do this (not tested):

(def local-storage (reagent/atom))

(rf/reg-sub-raw
  ::open?
  (fn [db [_]]
    (reagent.ratom/reaction (get @local-storage ::open?))))    

akiroz18:12:50

@joelsanchez My understanding of re-frame is that the DB is the single source of truth of your app. The reason why we have cofx is because we external information to modify our state / source of truth sometimes while keeping effect handlers pure.

akiroz18:12:30

if you want your app to react to external information changes these must go through the event loop and app-db before reaching your view

shaun-mahood18:12:32

@joelsanchez: Have you got a specific use case that requires you to get local-storage directly? Do you need to react to changes in local-storage that are coming from some source external to your application? It seems like there are a lot of potential problems related to both performance and consistency that could crop up. I've given a decent amount of thought to subscription coeffects a bit of thought (long ago, related to datascript), and the most complete idea I could come up with is to build a layer on top of app-db, and use app-db as a viewmodel with a data source (datascript, local storage) feeding it. I suspect it would be an interesting and fun bit of work but not necessarily a good idea. Kind of changing the model analogy from MVC to MVVM. More consistent with re-frame is probably setting up some sort of watcher on local-storage, and firing off an event whenever it changes - then you can sync it to your app-db and use the regular subscription mechanics. It's an interesting thought experiment, hope you can come up with something that makes it nice to work with.

p-himik19:12:35

Interesting observation - as soon as some of the components that I've created and use in just a single project become reused in the same project, they start to really resemble re-com components. Meaning, they completely or almost stop using some predefined subscription/event vectors and just accept them (or ratoms) as parameters. Initially I tried to make subscriptions and event handlers as generic as I could, so when I reuse some component I could also reuse its subscriptions and event handlers. But it quickly became very frustrating to have to pass a multitude of parameters into every sub-component just so it could pass them to a generic subscription or event handler. Not sure if there's a lesson here - just wanted to share.

joelsanchez21:12:49

@akiroz Makes sense, now I understand why it's done this way @shaun-mahood Not exactly, it is a regular cookie warning, I should show it or not depending on local-storage. > More consistent with re-frame is probably setting up some sort of watcher on local-storage, and firing off an event whenever it changes That would be a good idea, but in my case the problem is too simple to require doing that. Source code below

shaun-mahood21:12:02

Are those set server side? Are they used anywhere outside your re-frame app? It seems like there should be a way to get them into your app-db so that you can quit worrying about them (depending on your constraints). Of course, if it's only that small bit of functionality and you're happy enough with it then it's probably not a big deal.

joelsanchez22:12:47

For the moment I'm only using local-storage for this, but keeping db and local-storage in sync seems simple with a raw subscription and a reaction (as I did in a prev. snippet)