timbo245
timbo245

Reputation: 194

Can't access data in my redux store react

I have a component that I am trying to access data from my redux store. I am able, through my dev tools, to see that the data is populating into the redux store. However when I try to console.log that data to see the data before I implement it into my component I am getting undefined.

Here is my react component.

import React, { Fragment, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Table } from 'react-bootstrap';
import Moment from 'react-moment';
import Button from '../components/Button';
import ActivitySummary from '../components/ActivitySummary';

import { projectsInfoDetails } from '../actions/projectInfoActions';
import { projectContacts } from '../actions/projectContactActions';

import SectionHeader from '../components/SectionHeader';
import Loader from '../components/Loader';
import Message from '../components/Message';

const ProjectScreen = ({ match }) => {
  const dispatch = useDispatch();

  const projectInfoDetails = useSelector(state => state.projectInfoDetails);
  const { loading, error, projects } = projectInfoDetails;

  const contactDetails = useSelector(state => state.contactDetails);
  const { projectContactDetails } = contactDetails;

  useEffect(() => {
    dispatch(projectsInfoDetails(match.params.id));
    dispatch(projectContacts(match.params.id));
  }, [dispatch, match]);

  console.log(projectContactDetails);

  return (
    <Fragment>
      <div>
        <SectionHeader sectionName='Project' />
        <Button buttonName='Edit Project' />
      </div>
      {loading ? (
        <Loader />
      ) : error ? (
        <Message variant='danger'>{error}</Message>
      ) : (
        <div style={{ backgroundColor: '#F8F8F8' }}>
          <Table className='borderless'>
            <tbody>
              <tr>
                <td>
                  <strong>Name: </strong>
                  {projects.name}
                </td>
                <td>
                  <strong>Status: </strong>
                  {projects.status}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>State: </strong>
                  {projects.state}
                </td>
                <td>
                  <strong>County: </strong>
                  {projects.county}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>Congressional District: </strong>
                  {projects.district}
                </td>
                <td>
                  <strong>Type: </strong>
                  {projects.type}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>Funding Source: </strong>
                  <br />
                  {`${projects.fundingSource} ${projects.fundingSourceName}`}
                </td>
                <td>
                  <strong>Funding Source Goal: </strong>
                  <br />
                  {projects.fundingSourceGoal}
                </td>
                <td>
                  <strong>Start Date: </strong>
                  <br />
                  <Moment format='MM/DD/YYYY'>{projects.startDate}</Moment>
                </td>
                <td>
                  <strong>End Date: </strong>
                  <br />
                  {projects.endDate === null ? (
                    ''
                  ) : (
                    <Moment format='MM/DD/YYYY'>{projects.endDate}</Moment>
                  )}
                </td>
                <td>
                  <strong>Funding Percent: </strong>
                  <br />
                  {projects.fundingPercent}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>Contact: </strong>
                  {projects.contact}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>Start Date: </strong>
                  <Moment format='MM/DD/YYYY'>
                    {projects.projectStartDate}
                  </Moment>
                </td>
                <td>
                  <strong>End Date: </strong>
                  {projects.projectEndDate === null ? (
                    ''
                  ) : (
                    <Moment format='MM/DD/YYYY'>
                      {projects.projectEndDate}
                    </Moment>
                  )}
                </td>
              </tr>
              <tr>
                <td colSpan='5'>
                  <strong>Goals and Objectives: </strong>
                  {projects.goalsAndObjectives}
                </td>
              </tr>
              <tr>
                <td colSpan='5'>
                  <strong>Success Description: </strong>
                  {projects.successDescription}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>Accountable Staff</strong>
                  {projects.accountableStaff &&
                    projects.accountableStaff.map(data => (
                      <tr key={data._id}>
                        {data.lastName}, {data.firstName}
                      </tr>
                    ))}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>Project ID: </strong>
                  {projects.projectId}
                </td>
              </tr>
            </tbody>
          </Table>
        </div>
      )}

      <ActivitySummary />
    </Fragment>
  );
};

export default ProjectScreen;

Here is my reducer:

import {
  PROJECT_CONTACT_REQUEST,
  PROJECT_CONTACT_SUCCESS,
  PROJECT_CONTACT_FAIL
} from '../constants/projectConstants';

export const projectContactReducer = (
  state = { projectContact: [] },
  action
) => {
  switch (action.type) {
    case PROJECT_CONTACT_REQUEST:
      return { loading: true, projectContact: [] };
    case PROJECT_CONTACT_SUCCESS:
      return { loading: false, projectContact: action.payload };
    case PROJECT_CONTACT_FAIL:
      return { loading: false, error: action.payload };
    default:
      return state;
  }
};

and finally my action call:

import axios from 'axios';
import {
  PROJECT_CONTACT_REQUEST,
  PROJECT_CONTACT_SUCCESS,
  PROJECT_CONTACT_FAIL
} from '../constants/projectConstants';

export const projectContacts = id => async dispatch => {
  try {
    dispatch({ type: PROJECT_CONTACT_REQUEST });

    const { data } = await axios.get(`/api/projects/${id}/projectscontact`);
    dispatch({
      type: PROJECT_CONTACT_SUCCESS,
      payload: data
    });
  } catch (error) {
    dispatch({
      type: PROJECT_CONTACT_FAIL,
      payload:
        error.response && error.response.data.message
          ? error.response.data.message
          : error.message
    });
  }
};

Here is what the response from the server looks like in my dev tools:

dev tools response

my guess is that it has something to do with the data not populating before the console.log, but cannot seem to access the data.

Thanks

TL

my combine reducers file:

import { createStore, combineReducers, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension';

import { projectDetailsReducer } from './reducers/projectReducer';
import { pageReducer } from './reducers/pageReducer';
import { projectInfoReducer } from './reducers/projectInfoReducer';
import { fundingSourceReducer } from './reducers/fundingSourcesReducer';
import { fundSourceReducer } from './reducers/fundingSourceReducer';
import { contactsReducer } from './reducers/contactsReducer';
import { contactReducer } from './reducers/contactReducer';
import { projectContactReducer } from './reducers/projectContactReducer';

const reducer = combineReducers({
  projectDetails: projectDetailsReducer,
  projectInfoDetails: projectInfoReducer,
  pageDetails: pageReducer,
  fundingSourceDetails: fundingSourceReducer,
  fundSourceDetails: fundSourceReducer,
  contactsDetails: contactsReducer,
  contactDetails: contactReducer,
  projectContactDetails: projectContactReducer
});

const initialState = {};

const middleware = [thunk];

const store = createStore(
  reducer,
  initialState,
  composeWithDevTools(applyMiddleware(...middleware))
);

export default store;

Upvotes: 0

Views: 83

Answers (1)

Pavel Alekseev
Pavel Alekseev

Reputation: 1222

You get projectContactDetails wrong. There is projectContact not projectContactDetails in state of the projectContactReducer reducer so you should get that like:

const contactDetails = useSelector(state => state.projectContactDetails);
const { projectContact } = contactDetails;

Upvotes: 1

Related Questions