Flux best practices: Stores dispatching actions, AJAX calls in Web API Utils?

ton picture ton · May 1, 2015 · Viewed 13.3k times · Source

enter image description here

I understand that this image has been the ultimate guide of most, if not all, Flux programmers. Having this flow in mind, I have a few questions:

  1. Is it correct/highly advisable to have all of my $.ajax calls inside my Web API Utils?
    • Callbacks call the action creators, passing the data in the process
  2. If I want my Store to make an AJAX call, I do have to call the Action Creator first, right? Is it fundamentally incorrect to call a function in Web API Utils directly from Store?
  3. Is there like a virtual one-sided arrow connecting from Store to Action Creators?
    • I have a lot of operations that do not go through views
  4. What are the Callbacks between Dispatcher and Store?
  5. What's the Web API here? Is this where you'd apply a RESTful API? Is there an example of this somewhere?
  6. Is it okay to have a logic involved (to know which Action to dispatch) in one of my Action Creators? Basically, this action receives the response from my AJAX call. This is a snippet:

    var TransportActions = {
        receiveProxyMessage: function (message, status, xhr) {
            switch (message) {
                case ProxyResponses.AUTHORIZED:
                    AppDispatcher.dispatch({
                        type: ActionTypes.LOGIN_SUCCESS,
                        reply: m
                    });
                    break;
                case ProxyResponses.UNAUTHORIZED:
                    AppDispatcher.dispatch({
                        type: ActionTypes.LOGIN_FAIL,
                        reply: m
                    });
                    break;
                ...
            }
        }
    }
    

I've seen a lot of different answers online, but I am still not sure how I would incorporate all of them in my application. TYIA!

Answer

Retozi picture Retozi · May 1, 2015

Is it correct/highly advisable to have all of my $.ajax calls inside my Web API Utils? Callbacks call the action creators, passing the data in the process.

Yes, you should put all your request into a single entity, i.e. the Web API Utils. They should dispatch the responses so any store can choose to act on them.

I wrote a blogpost a while ago showing one way on how to handle requests http://www.code-experience.com/async-requests-with-react-js-and-flux-revisited/

If I want my Store to make an AJAX call, I do have to call the Action Creator first, right? Is it fundamentally incorrect to call a function in Web API Utils directly from Store?

This is a good question, and as far as I have seen it, everybody does it a little different. Flux (from Facebook) does not provide a full answer.

There are generally two approaches you could take here:

  1. You can make the argument that a Store should not "ask" for any data, but simply digest actions and notify the view. This means that you have to fire "fetch" actions within the components if a store are empty. This means that you will have to check on every data-listening view if it has to fetch data. This can lead to code duplication, if multiple views listen to the same Store.

  2. The Stores are "smart" in the sense that if they get asked for data, they check if they actually have state to deliver. If they do not, they tell the API Utils to fetch data and return a pending state to the views.

    Please note that this "tell the API to fetch data" is NOT a callback based operation, but a "fire and forget" one. The API will dispatch actions once the request returns.

I prefer option 2 to option 1, and I've heard Bill Fisher from the Facebook team say that they do it like this as well. (see comments somewhere in the blogpost above)

so No it is not fundamentally wrong to call the Api directly from the Store in my opinion.

Is there like a virtual one-sided arrow connecting from Store to Action Creators?

Depending on your Flux implementation there might very well be.

What are the Callbacks between Dispatcher and Store?

They are the only functions that can actually change the state in a store! each Store registers a callback with the Dispatcher. All the callbacks get invoked whenever a action is dispatched. Each callback decides if it has to mutate the store given the action type. Some Flux libraries try to hide this implementation detail from you.

What's the Web API here? Is this where you'd apply a RESTful API? Is there an example of this somewhere?

I think in the picture the Web API rectangle represents the actual server, the API Utils are the ones that make calls to the server (i.e. $.ajax or superagent). It ist most likely a RESTful API serving JSONs.

General advice:

Flux is a quite loose concept, and exact implementations change from team to team. I noticed that Facebook has changed some approaches here and there over time as well. The exact cycle is not strictly defined. There are some quite "fixed" things though:

  1. There is a Dispatcher that dispatches all actions to all stores and permits only one action at the time to prevent event-chain hell.
  2. Stores are action receivers, and all state must be changed through actions.
  3. actions are "fire and forget" (no callbacks!)
  4. Views receive state from the store and fire actions

Other things are done differently from implementation to implementation