Search code examples
reactjsreact-reduxredux-sagareact-proptypes

why do i get cannot read property of undefined in mapstatetoprops in redux


After a call to the api , i get data back from the api which is passed back to the action which updates the state in the reducer. dashboardSaga.js

import { call, put, takeEvery } from 'redux-saga/effects';
import actionTypes from '../constants/ActionTypes';
import { getData } from '../services/DashboardService';
import {
  getDataForDashboardSuccess,
  getDataForDashboardError
} from '../actions/DashboardActions';

export function* GetDataForDashboard( action ) {
  try {
    const response = yield call( getData, action );
    yield put( getDataForDashboardSuccess( response ) );
  } catch ( error ) {
    yield put( getDataForDashboardError( error ) );
  }
}

export function* watchGetDataForDashboard() {
  yield takeEvery( actionTypes.GET_DATA_FOR_DASHBOARD, GetDataForDashboard );
}

The reducer success method: dashboardReducer.js

const initialState = {
  error: false,
  dashboard: {
    orderdashboardmodel: {
      rfs: '0',
      pending: '0',
      total: '0'
    },
    sitesdashboardmodel: {
      up: '0',
      down: '0',
      total: '0',
      notmonitored: '0'
    },
    support: {
      open: '0',
      late: '0',
      escalated: '0'
    }
  }
};
function getDashboardSuccess( state, action ) {
  return {
    ...state,
    dashboard: {
      orderdashboardmodel: {
        rfs: action.payload.order.rfs,
        pending: action.payload.order.pending,
        total: action.payload.order.total
      },
      sitesdashboardmodel: {
        up: action.payload.sites.up,
        down: action.payload.sites.down,
        total: action.payload.sites.total,
        notmonitored: action.payload.sites.notmonitored
      },
      support: {
        open: action.payload.support.open,
        late: action.payload.support.late,
        escalated: action.payload.support.escalated
      }
    }
  };
}

On the component where i started the call

static propTypes = {
    data: PropTypes.func,
    getDataForDashboard: PropTypes.func
  };

  componentDidMount() {
    this.props.getDataForDashboard( 'hello' );
  }

  render() {
    const {
      data
         } = this.props;
    return (
<div>
{data.orderdashBoardmodel.rfs}
</div>
)};

const mapStateToProps = state => ( { data: state.dashboardReducer } );

const mapDispatchToProps = dispatch =>
  bindActionCreators( { getDataForDashboard }, dispatch );

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

it give error Cannot read property 'rfs' of undefined.

how can i access the value that is set in reducer in the component which started the call.


Solution

  • To assure using rfs:

    {data && data.orderdashBoardmodel && data.orderdashBoardmodel.rfs}
    

    Also, mapping state should be:

    const mapStateToProps = state => ( { data: state.dashboardReducer.dashboard } );