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

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


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


  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.

Absolutely.

  1. 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?

First, ask yourself why your store needs to do an API call. The only reason I can think of is that you want to cache the received data in the stores (I do this).

In the most simple Flux implementations, all Actions are created from only the View and Server. For example, a user visits a "Profile" view, the view calls a profileRequest action creator, the ApiUtils is called, some data comes in, a ServerAction is created, the ProfileStore updates itself and the ProfileView does accordingly.

With caching: the ProfileView ask the ProfileStore for some profile, the store doesn't have it, so returns an empty object with state 'loading', and calls ApiUtils to fetch that profile (and forgets about it). When the call finishes, a ServerAction will be created, the ProfileStore will update itself, etc. This works fine. You could also call and ActionCreator from the store, but I don't see the benefit.

MartyJS does something similar. Some flux implementations do the same with promises.

I think the important part is: when data comes back into the system, a ServerActionCreator is called with the new data. This then flows back into the stores.

I believe stores should only query data, all state-changing actions (updating stuff) should be user-initiated (come from views). Engineers from Facebook wrote about this here: https://news.ycombinator.com/item?id=7719957

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

If you want your stores to be smart: yes. If you want your app to be simple: no, go through Views.

  1. What are the Callbacks between Dispatcher and Store?

These are the dispatch handlers you find in stores. The dispatcher fires an action, stores listen to this fire event and do something with the action/payload.

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

This is where your ajax calls go. Typically this will mean some REST API, but could als be websockets or whatever. I've always loves this tutorial: http://fancypixel.github.io/blog/2015/01/29/react-plus-flux-backed-by-rails-api-part-2/

Disclaimers: these are my interpretations of Flux. Flux itself doesn't really solve fetching data, that's why they've come up with Relay and GraphQL at FB