Fork me on GitHub
#re-frame
<
2021-02-13
>
Clément Ronzon00:02:06

Hey guys, is there a way to "merge" the response of 2 asynchronous XHR events (sent using day8.re-frame-http-fx) the same way we could do it with promise in JS: Promise.all ?

p-himik04:02:19

Accumulate them in app-db and do the next thing when the accumulator size reaches the right one.

Clément Ronzon22:02:46

Thanks @U2FRKM4TW, I had that in mind too. So there is no standard/re-frame way to achieve that.

Mikko Koski08:02:35

@U01EGMY9273 For simple cases (2 XHR events) I'd do what @U2FRKM4TW suggested, for more complex flows have a look at https://github.com/day8/re-frame-async-flow-fx

Mikko Koski08:02:18

With re-frame-async-flow-fx you can do something like {:when :seen-both? [:requst-1-success :request-2-success] :dispatch [:both-requests-done]}

p-himik08:02:26

Correct me if I'm wrong but that approach seems to be susceptible to race conditions.

p-himik08:02:52

With the manual accumulator approach, you can at least incorporate some data to group related results together.

Mikko Koski12:02:42

Ummh.. not sure I fully follow what type of race condition your thinking. Are you talking about the order in which the responses come (1 first, then 2 or vice versa)? I guess not because the order shouldn't matter here. Or are you talking about a case where some other part of the app triggers the XHR which then dispatches e.g. :request-1-success, and then the seen-both? wouldn't wait for the future request 1 anymore because it saw one already?

p-himik13:02:19

Suppose you have :xhr-1 emitting :request-1-success and :xhr-2 emitting :request-2-success. And you have :main-event that issues both :xhr-1 and :xhr-2. With the above :when flow you will end up seeing :both-requests-done some time after emitting :main-event. So far so good (let's assume that requests never fail for simplicity). What will happen when you emit :main-event two times?

Clément Ronzon15:02:10

Thank you for the link @U0K7B1LM9. Awesome discussion here! 🙂

Mikko Koski18:02:34

Ah, got it, thanks for explaining. Indeed, the :when :seen-both? approach is susceptible for race conditions as you pointed out with the :main-event example. If that's a concern that needs to be taken care of, then some additional acrobatics is needed. There are cases, e.g. application boot up (which is what they mention in the README) where this isn't a concern: application boot up happens only once. The README mentions that you can use functions as an event predicate, so I guess that could be used to handle the situation if the :main-event includes some kind of group-id: (rf/dispatch [:main-event 1) (rf/dispatch [:main-event 2) {:when :seen? :events (fn [[_ group-id]] (= expected-group-id group-id)) ...} Disclaimer: I haven't tested this, and honestly, haven't used the async-flow library very much 🙂