Waiting for multiple actions before proceeding in redux-saga

349 views Asked by At

Assume that you have a saga that fetches a list of items. For each fetched item you also need a companion object. The pseudo-code below fetches some users from an API and for each user is emitting a new action to fetch her avatar.

function* fetchUsers() {
  try {
    const users = yield call(getUsers)
    yield all(
      users.map(({id}) => id).map(id => put(fetchUserAvatar(id)))
    )

    yield put('FETCH_USER_SUCCESS')
  } catch(e) {
    yield put('FETCH_USER_FAILURE')
  }
}

I would like to emit FETCH_USER_SUCCESS only when all avatars have been fetched i.e. fetchUserAvatar saga has emitted either FETCH_USER_AVATAR_SUCCESS or FETCH_USER_AVATAR_FAILURE.

So, I implemented the following solution:

function* fetchUsers() {
  try {
    const users = yield call(getUsers)
    yield all(
      users.map(({id}) => id).map(id => put(fetchUserAvatar(id)))
    )

    for(let i = 0; i < users.length; i++) {
      yield take(['FETCH_USER_AVATAR_SUCCESS', 'FETCH_USER_AVATAR_FAILURE'])
    }

    yield put('FETCH_USER_SUCCESS')
  } catch(e) {
    yield put('FETCH_USER_FAILURE')
  }
}

which feels a little ugly to me. Is there any effect such as takeN or a similar technique where I can wait for N actions to be emitted before proceeding? Or is there any alternative solution for the above problem?

0

There are 0 answers