re-frame

https://github.com/Day8/re-frame/blob/master/docs/README.md https://github.com/Day8/re-frame/blob/master/docs/External-Resources.md
Clément Ronzon 2021-02-13T00:26:06.100Z

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 ?

Clément Ronzon 2021-02-13T22:33:46.100400Z

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

rap1ds 2021-02-15T08:40:35.101200Z

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

rap1ds 2021-02-15T08:43:18.101500Z

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-himik 2021-02-15T08:44:26.101700Z

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

p-himik 2021-02-15T08:44:52.101900Z

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

rap1ds 2021-02-15T12:38:42.102300Z

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-himik 2021-02-15T13:06:19.102500Z

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 Ronzon 2021-02-15T15:09:10.102700Z

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

rap1ds 2021-02-15T18:48:34.102900Z

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 🙂

p-himik 2021-02-13T04:31:19.100200Z

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

Clément Ronzon 2021-02-13T22:33:46.100400Z

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