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
?
Thanks @p-himik, I had that in mind too. So there is no standard/re-frame way to achieve that.
@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
With re-frame-async-flow-fx you can do something like
{:when :seen-both? [:requst-1-success :request-2-success] :dispatch [:both-requests-done]}
Correct me if I'm wrong but that approach seems to be susceptible to race conditions.
With the manual accumulator approach, you can at least incorporate some data to group related results together.
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?
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?
Thank you for the link @rap1ds. Awesome discussion here! 🙂
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 🙂
Accumulate them in app-db and do the next thing when the accumulator size reaches the right one.