0

I have a Calendar component which, when rendered with a certain prop called LoadOnMount needs to call the server to load a set of flights.

The problem is that I update the calendar by listening to the CalendarStore's Events.UPDATE event, which is triggered by the UPDATE_CALENDAR action dispatched by my Dispatcher, and I load the set of flights using another action called LOAD_FLIGHT_LIST. So when I invoke this new action from the Calendar component's ComponentDidMount function I get the cannot dispatch in the middle of a dispatch error.

Any way to handle these sorts of dependencies? (The calendar is also fetched from the server)

nicohvi
  • 2,270
  • 2
  • 28
  • 42
  • Are you waiting on 2 or more async calls to the store in your component? If I understand correctly it seems like you are trying to mount a component twice. This won't work. If that is the problem I suggest using ```componentWillRecieveProps``` or ```shouldComponentUpdate```. Here you want to ensure you got back information from both of the async calls. (since you are using the same event for both calls). Correct me if I misunderstood your problem. – magnudae Mar 02 '15 at 13:53
  • Sorry, I might have worded my question badly: I only mount the component once, but it requires two calls to the server to fetch its data if some condition is true, but in a certain order. Perhaps this issue explains it better: https://github.com/facebook/flux/issues/168 – nicohvi Mar 03 '15 at 07:53
  • Are your async calls dispatched at the same time or can you do them consecutively? – magnudae Mar 03 '15 at 09:57
  • I'm doing them consecutively, the second call is only made if the response from the first call satisfy certain criteria. – nicohvi Mar 04 '15 at 10:15

1 Answers1

1

You have two issues that I can identify:

The first is that you are trying to get the dispatcher to dispatch during a dispatch. That's not the way you should be doing it.

The second is that you seem to be performing AJAX/async calls from inside your dispatch handler. I don't want to say that you should never do that, but that does not seem to be necessary in your application.

Here's a link to another stack overflow question that I think is similar: https://stackoverflow.com/a/23637463/2152216

The difference is that the asker is trying to perform an Ajax call from within his dispatch handler, while you seem to be trying to dispatch an event that will in turn trigger an ajax call during the event's handling.

What you can do is create an action that asynchronously loads the flight list, then dispatch the FLIGHT_LIST_LOADED action afterwards passing it the fetched flight list. Your store should handle this action and broadcast a change event for all the component observers.

I hope you understand what I'm talking about. If you think I misunderstood your problem, let me know.

Community
  • 1
  • 1
Desmond Lee
  • 707
  • 6
  • 17
  • My question is similar, but in the question he only needs to handle *one* AJAX call (which I can do just fine), instead of *two* (which is where I run into problems). You are correct in assuming that I want to make an AJAX call inside my dispatch handler, or - to be more precise - I want the handler to **initiate** an AJAX call. Your suggestion is good (I have looked into doing it this way), but how do you suggest I trigger the action to load the flight list if **not** in the actual dispatch handler? – nicohvi Mar 04 '15 at 10:17
  • I would trigger the action inside the async call. The action receives the result of the async call (the flight list). So you should make that call in your Calendar component's componentWillMount method, and trigger the action in the callback. – Desmond Lee Mar 04 '15 at 10:24
  • Well, the component doesn't know about the call since it's being abstracted away through the Actions singleton. The first action receives the data in its `success` handler, that is true - but that handler **also** dispatches the `UPDATE_CALENDAR` event. So if I, like you suggest, trigger the **second** action from within the `success` handler then I would run into the same problem of dispatching within a dispatch (since there's no guarantee that `UPDATE_CALENDAR` will have finished before the `LOAD_FLIGHT_LIST` event is dispatched). – nicohvi Mar 04 '15 at 10:49
  • It sounds like you want to trigger two actions: `UPDATE_CALENDAR` and `LOAD_FLIGHT_LIST`. But you want them to execute in order. Why do they need to execute in order? Is `LOAD_FLIGHT_LIST` also emitting a change event?, It should, since it changes something within the CalendarStore. – Desmond Lee Mar 04 '15 at 11:14
  • Here's an example that I made in jsfiddle. It has one store, `CalendarStore`, and two components, `MainView` and `CalendarView`: http://jsfiddle.net/deslee/jz2gt0av/4/ – Desmond Lee Mar 04 '15 at 11:17
  • I agree with Desmond here. You should just do the second call in the "callback" from the first call. This might, as the example shows, allow for some delay, but seems like the best solution to this problem. It behaves the same as with promises.(which were suggested earlier) – magnudae Mar 04 '15 at 13:40
  • Thanks very much for the detailed answer and suggestion, @DesmondLee. Thanks to you as well, magnudae. :-) – nicohvi Mar 04 '15 at 14:25