Fork me on GitHub
#re-frame
<
2020-09-24
>
Daniel Craig01:09:41

Hi, what’s the best way to subscribe to a list? Should I register a subscription for the whole list and then map across the elements with my view function, or is there some other way to subscribe to individual elements of a list that varies in length? I’m quite new to re-frame but I’ve read the tutorials once

kimim01:09:09

you can subscribe to the element of the list with subscript/index of the element

oliy13:09:51

would it make sense for run-test-sync to install an fx for :dispatch-later that did an immediate dispatch?

lispers-anonymous15:09:35

You could write a test fixture to do that. Does run-test-sync not automatically take care of that?

lispers-anonymous16:09:12

(defn dispatch-later-sync
  [f]
  (rf/reg-fx
   :dispatch-later
   (fn [value]
     (if (map? value)
       (rf/dispatch-sync (:dispatch value))
       (doseq [effect (remove nil? value)]
         (rf/dispatch-sync (:dispatch effect))))))
  (f))

(use-fixtures :once dispatch-later-sync)
Maybe something like this would work for you. Whether or not you should do it depends on your use case. If you have a test that hits some code using :dispatch-later and it fails because the test finishes before the dispatch, then it probably makes sense.

oliy18:09:39

It does not do it, I had to write it - I thought it would surprise people

oliy18:09:19

If you put it in a test fixture it will override for all tests. If it's inside run-test-sync then it will be removed at the end of the block

Rohan Nicholls11:09:46

I’ve run into exactly the same problem:

(cond....
(:toaster-bus/bus db)
  {:dispatch [:toaster-bus/remove curr-id]
   :dispatch-later [{:ms (+ transition-ms 30) ;; once remove is finished add new
        :dispatch [:toaster-bus/show message]}]}

Rohan Nicholls11:09:56

Basically, it has to wait for animations to finish. What I expected to happen was that run-test-sync would: • dispatch the first item (remove) • which runs an animation to remove the toaster, • when that is finished, removes the message from the db. • Then the :dispatch-later above kicks in, and • adds the new message to the db, • then runs the animation to show the toaster. In my test, it looks like the :dispatch-later is not happening, as the message after dispatching the initial message is the same.

Rohan Nicholls11:09:14

@UDVJE9RE3 I tried your code, but it lead to this error:

re-frame: while handling [:toaster-bus/hide] , dispatch-sync was called for [:toaster-bus/remove-message] . You can't call dispatch-sync within an event handler.

Rohan Nicholls12:09:54

Maybe I should just be using the async stuff? I’ll have a look and see if that solves my problem.

lispers-anonymous13:09:31

Yes calling rf/dispatch-sync is not allowed from reg-fx I found out. It might be worth digging into re-frame a little and just calling the function registered to the :dispatch fx directly in the test fixture code.

Rohan Nicholls13:09:38

Oh, that is a good idea.