Fork me on GitHub
#re-frame
<
2016-09-30
>
mikethompson01:09:04

@andre looking good! Can't grok the problem you are having, so can't suggest anything there. Need more explanation. @oliy nice to hear. It did all fall out nicely, I think. reg-sub was particularly satisfying to me personally. Would love to get some more time to take it ahead one more step too.

elahti03:09:19

i'll have to use 0.7.0 at work and it's super hard after using 0.8.0 😁 since the side-effects stuff is suddendly missing everywhere

shaun-mahood04:09:23

@elahti: The upgrade should be pretty painless, there shouldn’t be any breaking changes. Then you can sneak in some improvements 🙂

mikethompson05:09:51

@elahti I agree with @shaun-mahood there's not a lot to do in the "upgrade" to 0.8.0 UNLESS you have written your own middleware (in which case you'll have to rewrite them as interceptors, which is still fairly easy). For many, there is exactly nothing to do (although you will get deprecation warnings until you rename two functions).

elahti05:09:38

thanks! i know that i could just switch it in our project but i just want to communicate it with our (small) team first. laziness and all being a factor haven't just got into it yet 🙂

elahti05:09:30

excuses, i know

oliy06:09:16

@mikethompson reg-sub seemed to be one of the few bits that didn't change to me, what was new about that?

mikethompson07:09:30

@oliy pre 0.8.0 you wrote this:

(register-sub
 :sorted-items             ;; the query id
 (fn [db [_]]
   (let [items      (reaction (get-in @db [:some :path :to :items]))]  ;; reaction #1
         sort-attr  (reaction (get-in @db [:sort-by]))]                ;; reaction #2
       (reaction (sort-by @sort-attr @items)))))     
But with 0.8.0 you used reg-sub like this:
(reg-sub
  :sorted-items             ;; the query id
  :<-  [:items]             ;; assuming a subscription for :items exists
  :<-  [:sort-attr]        ;; assuming this subscription exists also 
  (fn [[items sort-attr]  _]
     (sort-by sort-attr items)))
You'll note that reaction is no longer used directly, neither are pesky @ necessary, plus, that way the handler is pure, and that way an efficient signal graph naturally materializes.

oliy07:09:06

Ah, I've seen that but not tried it yet. I'm not sure about the syntax. I've been using the 2-fn sub so no reactions in my code at the moment

oliy07:09:22

May have been using a 0.8 snapshot for that though!

akaivola07:09:00

mikethompson is the final argument to the reg-sub returning function the db itself? (fn [[items sort-attr] _] <- that _

danielcompton09:09:48

@akaivola that’s the subscription params IIRC

akaivola09:09:55

I was just wondering since before 0.8 register-sub got the db as it’s first argument. now I assume in reg-sub db is the last argument

akaivola09:09:09

it is in fact still the first argument

akaivola09:09:13

just checked the docs

akaivola09:09:41

ah, but that all works differently when you have :<- in there

akaivola09:09:53

still would like to know what that second argument is 🙂

andre11:09:48

some improvements in 0.1.4 before html debugger release - https://github.com/flexsurfer/re-frisk

mikethompson11:09:31

@akaivola sorry the docs on reg-sub are lacking ... best source of information is currently: https://github.com/Day8/re-frame/blob/master/examples/todomvc/src/todomvc/subs.cljs

akaivola11:09:31

line 71: ... and the 3rd one is for advanced cases, out of scope for this discussion.

akaivola11:09:35

No matter, I’ll get to it sometime later when elahti brings our project to 0.8.0 😄

mikethompson11:09:43

Ahh, that's all about dynamic subscriptions

akaivola11:09:01

oh, dynamic subscriptions I know about

mikethompson11:09:04

Look in the Wiki

akaivola11:09:13

I’m familiar with them

akaivola11:09:20

In one react-native (re-natal) IoT pet project I abused dynamic subscriptions to send sensor data

akaivola11:09:39

It was really nasty but effective 😄

mac12:09:55

I read up on how to do navigation using panels here https://github.com/Day8/re-frame/wiki/A-Larger-App, but what is best practice for navigation between tabs? Use a subscription to activate/deactivate the appropriate tab?

mikethompson12:09:30

State changes should happen via an event handler

mikethompson12:09:54

Events happen Event Handlers process them, causing state changes

mikethompson12:09:02

A change in tab is a state change

mac12:09:45

@mikethompson Sorry, that is what I meant handler sets active tab in db and tab activates/deactivates base on subscription to db.

mikethompson12:09:04

That navigation might also trigger the need for a data request from the server. Again, that's the domain of the event handler. It is responsible for looking after the change in the state of the app, including the process of getting more data.

mac12:09:45

@mikethompson Seems to me that handlers often require quite a few helpers (acces external datasources etc). Do these normally go directly in handlers.cljs or?

mikethompson12:09:48

These days the naming recomendation is events.cljs (not handlers.cljs, but yeah)

mac12:09:26

@mikethompson Template needs an update 🙂 would a patch be useful?

mikethompson12:09:58

That advice changed in v0.8.0 but not all docs and templates have caught up yet

mac21:09:42

What is the best approach to initializing the app-db based on the value of a Javascript promise? (in this case query to a PouchDB database)

shaun-mahood21:09:48

@mac Do you need to wait until the promise returns before initialization?

mac21:09:11

@shaun-mahood Yes, I need to ensure that the value from the promise has been inserted into app-db before anyhing else happens.

mikethompson21:09:34

Overall plan: 1. Put a good initial value into app-db (dispatch [:init]) ... perhaps use dispatch-sync 2. Kick off the query (probably in the event handler for :init) 3. On successful promise resolution, dispatch an event to say so (the handler for that event will change app-db further with the results of the query) 4. If the promise (query) fails, then dispatch an event for that too, the appropriate handler will then put the app into the right failed state.

mac21:09:52

@mikethompson Thanks, that makes a lot of sense.

johanatan21:09:00

Can you elaborate on what the "good initial value" might be? Just some constant (such as nil or :no-value) that the app will interpret properly?

shaun-mahood21:09:19

I'm not actually sure if it's necessary, but I've always been putting empty maps in my initial values for the things that would be populated later. So something like (def initial-state {:promise-result {}})

johanatan21:09:58

Oh, I did that for a few things but I've found that maps can be created automatically. Now I only do it for sets that I want to be able to conj into and disj from without worrying about creating it inline

johanatan21:09:16

i.e., assoc-in will create the intermediate levels automatically for you

shaun-mahood21:09:41

I generally have been doing it for my root keys, or for things that I want to register subscriptions on.

shaun-mahood21:09:08

Does the data key have to be there at the start if you want to use it for reg-sub?

johanatan21:09:17

Not sure about that one. Probably

shaun-mahood21:09:55

I think at some point it wasn't working for me if the key didn't exist at the start, and I've never revisited it since.

shaun-mahood21:09:53

But that was also when I started with Clojure so I could have been doing pretty much everything wrong. Now I figure I'm only likely to do some things wrong 🙂

johanatan22:09:22

Ha yea. I've found that you can usually ignore it for most data types

johanatan22:09:29

vectors, lists and maps particularly

johanatan22:09:43

sets you need to explicitly add to init-db

johanatan22:09:22

otherwise conj will create a list instead of adding the element to the empty set