Aminix
Aminix

Reputation: 158

React + Flux: best practice for calling an action after another action?

I have a component, let's call it List, that calls an action creator Action1.getItems(). After Action1.getItems() has retrieved information from a server, I need to call another action creator: Action2.getMoreItems(), which is a totally different action in a different file.

Facts:

  1. Both actions creators dispatch an action and change a store.
  2. I can't call Action2.getMoreItems() inside the _onChange() of List because it throws an error "Cannot dispatch in the middle of a dispatch ..."

Possibilities?

  1. Call Action2.getMoreItems() inside Action1.getItems() after the server returns
  2. Add a callback so I will have Action1.getItems(callback) and call Action2.getMoreItems() inside that callback from List component.

I believe this might be a very basic use of Flux but I still can't get my head around on how to get it right, both solutions look ugly to me.

Suggestions?

Thank you!

Upvotes: 4

Views: 3038

Answers (2)

Rico Herwig
Rico Herwig

Reputation: 1712

Most of the flux implementations have a method like "waitFor", which lets a store wait for another store to finish.

Assuming you need two execute 2 methods in your store: GetUser and GetPermissions. The first fetches a user and the latter the permissions, the fetched user has. Obviously, GetPermissions needs to wait for the user object to be fetched from the first method.

In this case, you would dispatch an action called GetUser and make both of your store functions listen to that action. So if you dispatch GetUser both store methods are executed.

In alt.js (flux implementation) and in many others, there are methods like waitFor(store), so GetPermissions can wait for the UserStore to fetch the user. In alt.js pseudocode this would look like this:

// UserStore
function getUser() {
    fetch('api/user').then(this.setState);
}

// PermissionsStore
function getPermissions() {
    this.waitFor(UserStore);
    let user = UserStore.getState().user;
    fetch('api/permission', user).then(this.setState);
}

This is, as I said, not working pseudocode, but it shows the concept. If you are interested, the flux implementation alt.js is great. Check it out at alt.js.org

Upvotes: 2

sma
sma

Reputation: 9597

Is getMoreItems dependent on the return value of getItems? If so, you can call the action in the .then callback of getItems.

If it's not, then you can invoke both calls at the same time and then concat the results of the promises.

So my vote is number 2 in your question. I don't think it's an ugly solution at all. You are delegating the responsibility of getting items and more items to your actions. The component itself is ignorant of that and simply dispatched a request for those items. How they're built should be transparent to the component.

Upvotes: 3

Related Questions