Winter
Winter

Reputation: 2517

react/redux/sagas - how to chain actions based on existing store data?

I am trying to fire actions inside of a saga based on if the state contains data or not.

Since I already have sagas for getting the data from books/games, I want to reuse that functionality. And I only want to fire those if the store is empty of that data.

This is my code so far...

function* getAllSaga(action) {
    try {

        let books = yield select(Selectors.books);
        let games = yield select(Selectors.games);

        if(!books.length || !games.length){
            yield put({ type: 'GET_BOOKS' });
            yield put({ type: 'GET_GAMES' });
        }

        books = yield select(Selectors.books);
        games = yield select(Selectors.games);

        const concated = books.concat(games);

        yield put({ type: 'GET_ALL_SUCCEEDED', all: concated });

    } catch (err) {
        yield put({ type: 'GET_ALL_FAILED', message: err.message });
    }
}

How should I solve this?

Upvotes: 0

Views: 721

Answers (1)

Martin Kadlec
Martin Kadlec

Reputation: 4985

puts are non blocking so you need to modify your code so that it waits for the new data like so:

function* getAllSaga(action) {
    try {

        let books = yield select(Selectors.books);
        let games = yield select(Selectors.games);

        if(!books.length || !games.length){
            yield put({ type: 'GET_BOOKS' });
            yield put({ type: 'GET_GAMES' });
            yield all([
                take('GET_BOOKS_SUCCEEDED'),
                take('GET_GAMES_SUCCEEDED')
            ])
            books = yield select(Selectors.books);
            games = yield select(Selectors.games);
        }

        const concated = books.concat(games);

        yield put({ type: 'GET_ALL_SUCCEEDED', all: concated });

    } catch (err) {
        yield put({ type: 'GET_ALL_FAILED', message: err.message });
    }
}

Upvotes: 1

Related Questions