4 ms·
We had talked about using promises at a lower level, but for actions it is very desired for them to be fire and forget. The view (component) fires the action in
by wingspan 12y ago
We had talked about using promises at a lower level, but for actions it is very desired for them to be fire and forget. The view (component) fires the action in response to some user interaction (e.g. clicking a button). The action is dispatched, and the stores listen for that action, update themselves, and then "inform", which notifies the component that its data has changed. In the case of data mutations, our action modules end up having a fair amount of logic in them:
1) User clicks a button to favorite an object, lets say an Article
2) View (component) listens for the click handler and calls ArticleActions.favorite(articleID)
3) ArticleActions.favorite fires a preliminary ARTICLE_UPDATE action, for any stores that want to update optimistically
4) ArticleActions.favorite calls into the ArticleDAO (the data access abstraction) via ArticleDAO.update, a function that takes an ID, some updates, and two callbacks, success and error.
5) In the success callback, ArticleActions.favorites fires off ARTICLE_UPDATE_COMPLETED, along with the updated article object
6) In the error callback, ArticleAction.favorites fires off ARTICLE_UPDATE_FAILED, along with the error
7) Stores listen for the COMPLETED and FAILED actions to know when to update their data, including stores that show error notices
As you can see,the action layer itself should not really be accepting callbacks/returning promises. It might be easier, however, if the DAO layer returned promises, and this is something we have talked about migrating to.
- EdwardMSmith 12y agoWhat 'part of Flux' is listening to(or triggering, for that matter) the ARTICLE_UPDATE, ARTICLE_UPDATE_COMPLETED, and ARTICLE_UPDATE_FAILED events? The dispatcher?
- wingspan 12y agoYes, it is the dispatcher. ArticleActions.update basically calls Dispatcher.dispatchAction(ARTICLE_UPDATE, {article: article})
- deleted 12y ago[deleted]
- zzzaim 12y agoFrom what I understand from your description, it seems that data access, server requests, etc. fall under the responsibility of Actions? Why not offload it to the Store? e.g: ArticleActions.favorite fires off an ARTICLE_UPDATE action, the ArticleStore receives this and does the appropriate ArticleDAO asynchronous call and when done emits a change event to update any Views.
- wingspan 12y agoWe split out data mutations from data access (see https://news.ycombinator.com/item?id=7721542 https://news.ycombinator.com/item?id=7721542). One reason is that multiple stores may be interested in the COMPLETE calls. One example is when you have a store that tracks which items in a list are selected; if one of the item is deleted, this separate store, say ArticleSelectionStore, needs to handle the ARTICLE_DELETE_COMPLETED event to unselect that article.
- gbrits 12y agoWould it be correct in saying that stores behave exactly (are) Eager Read Derivations as describe by Fowler? http://martinfowler.com/bliki/EagerReadDerivation.html http://martinfowler.com/bliki/EagerReadDerivation.html. I.e: they update themselves (eagerly, hence the name) based on changes from the data-access layer. They're able to choose themselves which transformations to do on the data in order for views/components to query them efficiently.
- spicyj 12y agoIt's unclear to me why it's important that actions be fire-and-forget. Is there no scenario in which you would want to show (next to the Favorite button) that favoriting failed but not care about other article-update failures?
- wingspan 12y agoSure, that is absolutely a valid scenario. This could be accomplished using a context object as I explained in my first comment, something like {changedFields: ['isFavorite'], error: 'some error message'}. You'd then have some store that listens for article update failures and saves the error message somewhere, and then your favorite button view would pull the data from there. The importance of keeping actions fire-and-forget is that data must live in the store; if actions have callbacks, the views would be using state to keep themselves updated with data that should be in the store.