Search code examples
reactjstypescriptreact-nativeredux-sagasaga

How to call one saga at the end of another redux-saga like a async await in redux-thunk


I have two sagas, one gets the cities, the other is the weather forecast for these cities (according to ID specialists), how can I make it so that the second saga is processed at the end of the first? method in which a call my sagas:

async componentDidMount() {
    this.props.navigation.setOptions(this.navigationOptions);

    //sagas call
   
        await this.props.fetchCities();
        await this.fetchForecastsHandler(this.props.userCities);
  }
 ...some code
 fetchForecastsHandler(cities: ICIty[]) {
    const ids = cities.map((el) => el.id);
    this.props.fetchForecasts(ids);
  }``


...some code
   render(){...}

My index.ts saga

export function* mySaga() {
    yield takeEvery(types.FETCH_USERS_CITIES, fetchUserCitiesWorker);
    yield takeEvery(types.REMOVE_CITY, removeUserCitiesWorker);
    yield takeEvery(types.SEARCH_CITY, searchUserCitiesWorker);

    yield takeEvery(types.FETCH_FORECAST, fetchForecastWorker);

    yield takeEvery(types.ADD_NOTIFICATION, addNotificationWorker);
    yield takeEvery(types.EDIT_NOTIFICATION, editNotificationWorker);
    yield takeEvery(types.DELETE_NOTIFICATION, deleteNotificationsWorker);
    yield takeEvery(types.FETCH_NOTIFICATION, fetchNotificationsWorker);
}

**FeychCityWorker saga:**


 export function* fetchUserCitiesWorker(callback?:any) {
    try {
        yield put({ type: types.FETCH_USERS_CITIES_START });
        //const user = yield call(Api.fetchUser, action.payload.userId);
        yield delay(2000,true)
        yield put({ type: types.FETCH_USERS_CITIES_SUCCESS, payload: userCities });
        console.log("fetchUserCitiesWorker worked sucess")
        //callback?callback():null
    } catch (e) {
        yield put({ type: types.FETCH_USERS_CITIES_ERROR, error: e.message });
    }
}

**also storage settings just in case:**
    
const sagaMiddleware = createSagaMiddleware()

export const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)
export const action = (type:string) => store.dispatch({type})

sagaMiddleware.run(mySaga)

Solution

  • You can update your componentDidMount to call only this.props.fetchCities. Update your watcher function mySaga to include

    {
      ...,
      yield takeEvery(
        [FETCH_USERS_CITIES_SUCCESS],
        fetchUserCitiesWorker,
      )
    }
    

    This will make the payload of FETCH_USERS_CITIES_SUCCESS available in the fetchUserCitiesWorker saga