0
votes

On dispatching the action LOGIN_CALLED one of the reducer which is listening to this action is working fine. But the watcher saga isn't triggering watcherLogin()

I have set breakpoints in watcherLogin() but they are never getting called. Moreover here createStore(persistedReducer, applyMiddleware(Logger, sagaMiddleware)) the Logger is getting called each time any action is fired.

Store Creation

import { createStore, applyMiddleware, combineReducers } from 'redux';
import createSagaMiddleware from 'redux-saga';
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage';

import { Logger } from '../middlewares';
import rootSaga from '../sagas';

import { errorReducer } from './error.reducer';
import appReducer from './app';
import uiReducer from './ui'


const persistConfig = {
    key: 'root',
    storage: storage,
    whitelist: [ 'app' ]
}

const reducers = combineReducers ({
    app: appReducer,
    ui: uiReducer,
    error: errorReducer
})

const sagaMiddleware = createSagaMiddleware()

const persistedReducer = persistReducer(persistConfig, reducers)

export default config = () => {
    let store = createStore(persistedReducer, applyMiddleware(Logger, sagaMiddleware))
    let persistor = persistStore(store)
    sagaMiddleware.run(rootSaga);
    return {
      store,
      persistor
    }
}

auth saga

import { authAction } from '../actions';
import { postLogin } from '../http/auth.http.service';
import { formatHTTPResponse } from './util.saga';
import { takeLatest, call, put } from 'redux-saga/effects';

export function* watcherLogin() {
    return takeLatest(authAction.LOGIN_CALLED, workerLogin)
}

export function* workerLogin(action) {
    const authResponse = yield call(
        postLogin,
        action.payload
    );
    let formattedResponse = formatHTTPResponse(authResponse);

    if (authResponse.ok) {

        yield put({
            type: authAction.LOGIN_SUCCESS,
            payload: authPayload
        })
    } else {
        yield put({
            type: authAction.LOGIN_FAILURE,
            error: formattedResponse    
        })
    }
}

Watcher saga

import { all, fork } from 'redux-saga/effects';
import { watcherLogin } from './auth.saga';

export default function* rootSaga() {
    yield all([
        watcherLogin()
    ]);
}

App.js

import React from 'react';
import { Provider } from 'react-redux';
import { PersistGate } from "redux-persist/integration/react";
import config from './src/reducers';
import Authentication from './src/route/Authentication';

let { store, persistor } = config();

class App extends React.Component{
  render() {
    return (
      <Provider store={store} >
        <PersistGate loading={null} persistor={persistor}>
          <Authentication />
        </PersistGate>
      </Provider>
    );
  }
}

export default App;

Component

import React from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import { connect } from 'react-redux';

import { authAction } from '../actions/index.js';

class Login extends React.Component {
    constructor(props, context) {
        super(props);
    }

    Login(event) {
        this.props.postLogin({
            body: {
                email: '[email protected]',
                password: 'password'
            }
        })
    }

    render() {
        return (
            <View>
                <TouchableOpacity onPress={this.Login.bind(this)} style={{ backgroundColor: '#75C35D' }}>
                    <Text style={{ color: '#fff' }}>SIGN IN</Text>
                </TouchableOpacity>        
            </View>
        );
    }
}

const mapStateToProps = (state) => ({
    // some lines of code here
})

const mapDispatchToProps = (dispatch) => ({
    postLogin: payload => dispatch({type: authAction.LOGIN_CALLED, payload})
})


export default connect(mapStateToProps, mapDispatchToProps)(Login);

react: 16.2.0
react-native: 0.52.0
react-redux: 5.0.7
redux: 4.0.0
redux-persist: 5.10.0
redux-saga: 0.16.0

1
Try wrapping the watcher in call/fork effect instead of calling it directly. (all([fork(watcherLogin)] ))Martin Kadlec

1 Answers

0
votes

You need to provide sagas to Provider.

<Provider store={{...store, runSaga: sagaMiddleware.run(rootSaga)}}>

Edit: The above is not necessary at all, ignore it. But I created a minimal example from your code, and it looks like if you change your rootSaga to the following, it works fine.

function* rootSaga() {
    yield [
        takeLatest(authAction.LOGIN_CALLED, workerLogin)
    ];
}

Not sure why, but I am looking into it's documentation. Would update if found anything.