I'm creating a react.js application with flux architecture and I am trying figure out where and when a request for data from the server should be made. Is there a any example for this. (Not TODO app!)
6 Answers
I'm a big proponent of putting async write operations in the action creators and async read operations in the store. The goal is to keep the store state modification code in fully synchronous action handlers; this makes them simple to reason about and simple to unit test. In order to prevent multiple simultaneous requests to the same endpoint (for example, double-reading), I'll move the actual request processing into a separate module that uses promises to prevent the multiple requests; for example:
class MyResourceDAO {
get(id) {
if (!this.promises[id]) {
this.promises[id] = new Promise((resolve, reject) => {
// ajax handling here...
});
}
return this.promises[id];
}
}
While reads in the store involve asynchronous functions, there is an important caveat that the stores don't update themselves in the async handlers, but instead fire an action and only fire an action when the response arrives. Handlers for this action end up doing the actual state modification.
For example, a component might do:
getInitialState() {
return { data: myStore.getSomeData(this.props.id) };
}
The store would have a method implemented, perhaps, something like this:
class Store {
getSomeData(id) {
if (!this.cache[id]) {
MyResurceDAO.get(id).then(this.updateFromServer);
this.cache[id] = LOADING_TOKEN;
// LOADING_TOKEN is a unique value of some kind
// that the component can use to know that the
// value is not yet available.
}
return this.cache[id];
}
updateFromServer(response) {
fluxDispatcher.dispatch({
type: "DATA_FROM_SERVER",
payload: {id: response.id, data: response}
});
}
// this handles the "DATA_FROM_SERVER" action
handleDataFromServer(action) {
this.cache[action.payload.id] = action.payload.data;
this.emit("change"); // or whatever you do to re-render your app
}
}

- 157,729
- 40
- 374
- 311
-
Have you tried to put promises inside action payloads? I find it more easy to deal with than dispatching multiple actions – Sebastien Lorber Oct 29 '14 at 23:54
-
@SebastienLorber The big draw to flux for me is keeping all state updates in a synchronous code path, and explicitly *only* as a result of action dispatches, so I avoid asynchrony inside the stores. – Michelle Tilley Oct 29 '14 at 23:58
-
@BrandonTilley - I followed your fluxxor post. very nice and logical! For server-side rendering through fluxxor, we would have to have the Fluxxor.createStore's initialize function load the initial data. How would you suggest going about this? Is there some way to make the flux object (and hence actions) available in the store's initialize (would this even work?)? Or would it be best to just call the api directly? – Federico Jan 15 '15 at 00:41
-
1@Federico It's unclear to me still what the "best" solution is. I've been experimenting with this strategy for data loading combined with counting the number of outstanding async requests. Unfortunately `flux` is injected into stores after construction, so no great way to get actions in the initialize method. You might find some good ideas from Yahoo's isomorophic flux libs; this is something Fluxxor v2 should support better. Feel free to email me if you want to chat about this more. – Michelle Tilley Jan 15 '15 at 00:46
-
1`data: result` should be `data : data`, right? there is no `result`. perhaps better to rename the data param to payload or something like that. – oligofren Mar 08 '15 at 23:15
-
@BinaryMuse Shouldn't the 'return this.cache[primaryKey]' statement in the code example above be outside of the 'else' branch? In the current situation, the 'LOADING_TOKEN' value will never be returned to the caller of the getSomeData method. Further more, where does the 'primaryKey' value in the 'updateFromServer' method come from? I know this is just a code example, but I was wondering whether I did understand it right or not, because I think I will incorporate this principle in my own react Flux application. – Björn Boxstart Apr 08 '15 at 07:41
-
@BjörnBoxstart You're correct on the if statement—a typo that has been fixed. I also updated the pseudocode to make it more obvious where the `primaryKey` comes from (it's in the server response). – Michelle Tilley Apr 09 '15 at 16:03
-
2I found [this old thread](https://groups.google.com/forum/#!topic/reactjs/jBPHH4Q-8Sc) to be very helpful - in particular, Bill Fisher and Jing Chen's comments. This is very close to what @BinaryMuse is proposing with the minor difference that dispatching happens in the action creator. – phillipwei May 23 '15 at 01:51
-
Just to be clear--I want to make sure I understand--your Store requests the data, and upon receiving it, it fires an action, and it also _subscribes to that same action_, right? (The idea being that other stores could act upon receipt of the same data.) – Lane Rettig Jan 21 '16 at 18:25
Fluxxor has an example of async communication with an API.
This blog post has talks about it and has been featured on React's blog.
I find this a very important and difficult question that is not clearly answered yet, as frontend software synchronization with the backend is still a pain.
Should API requests be made in JSX components? Stores? Other place?
Performing requests in stores mean that if 2 stores need the same data for a given action, they will issue 2 similar requets (unless you introduce dependencies between stores, which I really don't like)
In my case, I have found this very handy to put Q promises as payload of actions because:
- My actions do not need to be serializable (I do not keep an event log, I don't need event replay feature of event sourcing)
- It removes the need to have different actions/events (request fired/request completed/request failed) and have to match them using correlation ids when concurrent requests can be fired.
- It permits to multiple store to listen to the completion of the same request, without introducing any dependency between the stores (however it may be better to introduce a caching layer?)
Ajax is EVIL
I think Ajax will be less and less used in the near future because it is very hard to reason about. The right way? Considering devices as part of the distributed system I don't know where I first came across this idea (maybe in this inspiring Chris Granger video).
Think about it. Now for scalability we use distributed systems with eventual consistency as storage engines (because we can't beat the CAP theorem and often we want to be available). These systems do not sync through polling each others (except maybe for consensus operations?) but rather use structures like CRDT and event logs to make all the members of the distributed system eventually consistent (members will converge to the same data, given enough time).
Now think about what is a mobile device or a browser. It is just a member of the distributed system that may suffer of network latency and network partitionning. (ie you are using your smartphone on the subway)
If we can build network partition and network speed tolerant databases (I mean we can still perform write operations to an isolated node), we can probably build frontend softwares (mobile or desktop) inspired by these concepts, that work well with offline mode supported out of the box without app features unavailability.
I think we should really inspire ourselves of how databases are working to architecture our frontend applications. One thing to notice is that these apps do not perform POST and PUT and GET ajax requests to send data to each others, but rather use event logs and CRDT to ensure eventual consistency.
So why not do that on the frontend? Notice that the backend is already moving in that direction, with tools like Kafka massively adopted by big players. This is somehow related to Event Sourcing / CQRS / DDD too.
Check these awesome articles from Kafka authors to convince yourself:
- STREAM PROCESSING, EVENT SOURCING, REACTIVE, CEP… AND MAKING SENSE OF IT ALL
- The Log: What every software engineer should know about real-time data's unifying abstraction.
Maybe we can start by sending commands to the server, and receiving a stream of server events (through websockets for exemple), instead of firing Ajax requests.
I have never been very comfortable with Ajax requests. As we React developpers tend to be functional programmers. I think it's hard to reason about local data that is supposed to be your "source of truth" of your frontend application, while the real source of truth is actually on the server database, and your "local" source of truth may already be outdated when you receive it, and will never converge to the real source of truth value unless you press some lame Refresh button... Is this engineering?
However it's still a bit hard to design such a thing for some obvious reasons:
- Your mobile/browser client has limited resources and can not necessarily store all the data locally (thus sometimes requiring polling with an ajax request heavy content)
- Your client should not see all the data of the distributed system so it requires somehow to filter the events that it receives for security reasons

- 1
- 1

- 89,644
- 67
- 288
- 419
-
3
-
@MattFoxxDuncan not sure it's such a good idea as it makes the "event log" unserializable and makes the store update asynchronously on actions being fired, so it has some drawbacks However If it's ok for your usecase and you understand these drawbacks it's quite handy and reduce boilerplate. With Fluxxor you can probably do something like `this.dispatch("LOAD_DATA", {dataPromise: yourPromiseHere});` – Sebastien Lorber Jan 18 '15 at 00:22
-
Completely disagree about your AJAX argument. In fact it was very annoying to read. Have you read your remarks? Think of stores, games, apps that make serious money - all require API and AJAX server calls.. look at Firebase if you want "serverless" or something of that nature but AJAX is here to say I hope at least no one else agrees with your logic – TheBlackBenzKid Nov 30 '16 at 08:36
-
@TheBlackBenzKid I'm not saying Ajax will disappear totally in the year (and be sure I'm still building websites on top of ajax requests currently as a CTO of a startup), but I'm saying it'l likely to disappear because it's not a protocol good enough to handle eventual consistency which rather require streaming and not polling, and eventual consistency is what permits to make apps work offline reliably (yes you can hack something with localstorage yourself, but you'll have limited offline capacities, or your app is very simple). The problem is not caching, it's invalidating that cache. – Sebastien Lorber Nov 30 '16 at 10:36
-
@TheBlackBenzKid The models behind Firebase, Meteor etc is not good enough. Do you know how these systems handle concurrent writes? last-write-win instead of causal consitency/merging strategies? Can you afford overriding work of your collegue in an app when both are working on unreliable connections? Also note that these systems tend to couple a lot the local and server modelisations. Do you know any well known collaborative app that is significantly complex, works perfectly offline, declaring being a satisfied Firebase user? I don't – Sebastien Lorber Nov 30 '16 at 10:40
-
@TheBlackBenzKid I'm not sure what we disagree on them, because I agree that current web specs are not yet good enough to build the kind of architecture I propose here, and that we still need to rely on Ajax today to make money. However please reconsider my opinions after reading some resource on the subject of log/event-stream based backend systems, distributed systems theory... A good pragmatic introduction is https://www.confluent.io/blog/turning-the-database-inside-out-with-apache-samza/ – Sebastien Lorber Nov 30 '16 at 10:45
-
Hi @SebastienLorber I am reading the article and will share my thoughts shortly. So far, it sounds good. – TheBlackBenzKid Nov 30 '16 at 12:59
You can call for data in either the action creators or the stores. The important thing is to not handle the response directly, but to create an action in the error/success callback. Handling the response directly in the store leads to a more brittle design.

- 12,658
- 4
- 28
- 27
-
9Can you explain this in more details please? Say i need to make initial data loading from the server. In the controller view i start an action INIT, and the Store starts it's async initialization reflecting to this action. Now, i would go with the idea, that when the Store fetched the data, it would simply emit change, but not start an action. So emitting a change after initialization tells the views that they can get the data from the store. Why is there a need **not** to emit a change upon successful loading, but starting another action?! Thanks – Attila Kling Oct 31 '14 at 10:05
-
Fisherwebdev, about stores calling for data, by doing so, don't you break the Flux paradigm, the only 2 proper ways i can think of to call for data is by using: 1. use a bootstrap class using Actions to load data 2. Views, again using Actions to load data – Yotam Jan 12 '15 at 21:19
-
4Calling for data is not the same thing as receiving data. @Jim-Y: you should only emit change once the data in the store has actually changed. Yotam: No, calling for data in the store does not break the paradigm. Data should only be received through actions, so that all the stores may be informed by any new data entering the application. So we can call for data in a store, but when the response comes back, we need to create a new action instead of handling it directly. This keeps the application flexible and resilient to new feature development. – fisherwebdev Mar 18 '15 at 08:13
I have been using Binary Muse's example from the Fluxxor ajax example. Here is my very simple example using the same approach.
I have a simple product store some product actions and the controller-view component which has sub-components that all respond to changes made to the product store. For instance product-slider, product-list and product-search components.
Fake Product Client
Here is the fake client which you could substitute for calling an actual endpoint returning products.
var ProductClient = {
load: function(success, failure) {
setTimeout(function() {
var ITEMS = require('../data/product-data.js');
success(ITEMS);
}, 1000);
}
};
module.exports = ProductClient;
Product Store
Here is the Product Store, obviously this is a very minimal store.
var Fluxxor = require("fluxxor");
var store = Fluxxor.createStore({
initialize: function(options) {
this.productItems = [];
this.bindActions(
constants.LOAD_PRODUCTS_SUCCESS, this.onLoadSuccess,
constants.LOAD_PRODUCTS_FAIL, this.onLoadFail
);
},
onLoadSuccess: function(data) {
for(var i = 0; i < data.products.length; i++){
this.productItems.push(data.products[i]);
}
this.emit("change");
},
onLoadFail: function(error) {
console.log(error);
this.emit("change");
},
getState: function() {
return {
productItems: this.productItems
};
}
});
module.exports = store;
Now the product actions, which make the AJAX request and on success fire the LOAD_PRODUCTS_SUCCESS action returning products to the store.
Product Actions
var ProductClient = require("../fake-clients/product-client");
var actions = {
loadProducts: function() {
ProductClient.load(function(products) {
this.dispatch(constants.LOAD_PRODUCTS_SUCCESS, {products: products});
}.bind(this), function(error) {
this.dispatch(constants.LOAD_PRODUCTS_FAIL, {error: error});
}.bind(this));
}
};
module.exports = actions;
So calling this.getFlux().actions.productActions.loadProducts()
from any component listening to this store would load the products.
You could imagine having different actions though which would respond to user interactions like addProduct(id)
removeProduct(id)
etc... following the same pattern.
Hope that example helps a bit, as I found this a little tricky to implement, but certainly helped in keeping my stores 100% synchronous.

- 22,878
- 21
- 90
- 105
I answered a related question here: How to handle nested api calls in flux
Actions are not supposed to be things that cause a change. They are supposed to be like a newspaper that informs the application of a change in the outside world, and then the application responds to that news. The stores cause changes in themselves. Actions just inform them.
Bill Fisher, creator of Flux https://stackoverflow.com/a/26581808/4258088
What you basically should be doing is, stating via actions what data you need. If the store gets informed by the action, it should decide if it needs to fetch some data.
The store should be responsible for accumulating/fetching all the needed data. It is important to note though, that after the store requested the data and gets the response, it should trigger an action itself with the fetched data, opposed to the store handling/saving the response directly.
A stores could look like something like this:
class DataStore {
constructor() {
this.data = [];
this.bindListeners({
handleDataNeeded: Action.DATA_NEEDED,
handleNewData: Action.NEW_DATA
});
}
handleDataNeeded(id) {
if(neededDataNotThereYet){
api.data.fetch(id, (err, res) => {
//Code
if(success){
Action.newData(payLoad);
}
}
}
}
handleNewData(data) {
//code that saves data and emit change
}
}

- 1
- 1

- 6,684
- 6
- 24
- 44
Here's my take on this: http://www.thedreaming.org/2015/03/14/react-ajax/
Hope that helps. :)

- 920
- 8
- 11
-
8downvote per the guidelines. putting answers on external sites makes this site less useful, and makes for lower quality answers, lowering the usefulness of the site. external urls will probably break in time too. the downvote does not say anything about the usefulness of the article, which by the way is very good :) – oligofren Mar 16 '15 at 09:59
-
2Good post, but adding a short summary of pros / cons of each approach will get you upvotes. On SO, we shouldn't need to click a link to get the gist of your answer. – Cory House Jul 11 '15 at 12:20