Kevin Danikowski
Kevin Danikowski

Reputation: 5196

Why takeLeading redux-sagas isn't working

I'm not quite sure why takeLeading isn't working for me (takeLeading is supposed to take the first call and ignore subsequent calls until the first is returned). It's calling the same call 3 separate times like a takeEvery with the same parameters from 3 separate components in their useEffect(() => {getApiWatcher(params)}, []) on mount hook. It appears those don't return before the second is called either so I know it's not 3 uniquely separate calls.

function getApi(params) {
    console.log('GET CALL') // called 3 times in console and network tab
    return Api.doCall(
        `API/${params.number}/${params.type}`,
        'GET'
    );
}

function* getApiActionEffect(action) {
    const { payload } = action;
    try {
        const response = yield call(getApi, payload);
        yield put(getApiSuccess({ data: response.data, status: response.status }));
    } catch (e) {
        yield put(getApiError(e.response));
    }
}

export function* getApiActionWatcher() {
    yield takeLeading( // should make sure only first call is made and subsequent are ignored
        GET_API_WATCHER,
        getApiActionEffect
    );
}


// action
export function getApiWatcher(payload) {
    return { type: GET_API_WATCHER, payload };
}

// passed dispatch as props
const mapDispatchToProps = (dispatch) => bindActionCreators( { getApiWatcher, }, dispatch ); 

// root saga
export default function* rootSaga() {
    yield all([... getApiActionWatcher(),...])
}

There is a lot more code involved so I'm not creating a sample jsfiddle, but ideas for what could potentially be going wrong are what I'm looking for! Might have over looked something.

Upvotes: 1

Views: 2171

Answers (3)

Kevin Danikowski
Kevin Danikowski

Reputation: 5196

Turns out there were duplicate imported functions in the root saga. For example:

// root saga
export default function* rootSaga() {
    yield all([
        ... getApiActionWatcher(),...
        ... getApiActionWatcher(),...
    ])
}

Removing the duplicates solved the issue. It also removed other duplicate calls I wasn't working on.

Upvotes: 1

asdsad asd asdas
asdsad asd asdas

Reputation: 1

takeLeading is working as intended. The calls to getApi instantly returns.

The only way your code would work the way you want it to is if getApi returns a Promise. If getApi() were to return a Promise, the getApiActionEffect would block until the Promise resolved.

Upvotes: 0

Anton Bakinowsky
Anton Bakinowsky

Reputation: 352

If you want to handle every GET_API_WATCHER action then you better takeEvery redux-saga helper.

And docs says that task spawned with takeLeading blocks others tasks until it's done.

Upvotes: 0

Related Questions