TransWikia.com

React redux prop object property undefined

Stack Overflow Asked by bbarriatos on March 1, 2021

I am new to React Redux. I am not sure what is wrong on my code. There is no error on the terminal but when I take a look on the browser there is a TypeError. ItemsProduct was on the props. I was wondering why it returns an error when I am trying to access the properties.

productDescription.js

import React, { Component } from "react";
import { Link } from "react-router-dom";

import { connect } from "react-redux";
import axios from "axios";

import {
  fetchProductsRequests,
  fetchProductsSuccess,
  fetchProductError,
} from "../../actions/productActions";

class ProductDescription extends Component {
  componentDidMount() {
    this.props.fetchProducts();
  }

  render() {
    return (
      <>
        <div className="grid grid-cols-3 gap-6 mb-10">
          <div className="col-start-2 col-end-4">
            <h4>{this.props.itemsProduct[0].name}</h4>
          </div>
        </div>
      </>
    );
  }
}

const mapStateToProps = (state, ownProps) => {
  return {
    itemsProduct: state.rootProduct.products.filter(
      (prod) => prod.id == ownProps.match.params.id
    ),
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    fetchProducts: () => {
      dispatch(fetchProductsRequests());
      axios
        .get("http://localhost:3000/js/products.json")
        .then((response) => {
          dispatch(fetchProductsSuccess(response.data));
        })
        .catch((error) => {
          dispatch(fetchProductError(error.message));
        });
    },
  };
};

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

productActions.js

export const FETCH_PRODUCTS_REQUESTS = "FETCH_PRODUCTS_REQUESTS";
export const FETCH_PRODUCTS_SUCCESS = "FETCH_PRODUCTS_SUCCESS";
export const FETCH_PRODUCTS_ERROR = "FETCH_PRODUCTS_ERROR";

export const fetchProductsRequests = () => {
  return {
    type: FETCH_PRODUCTS_REQUESTS,
  };
};

export const fetchProductsSuccess = (product) => {
  return {
    type: FETCH_PRODUCTS_SUCCESS,
    payload: product,
  };
};

export const fetchProductError = (error) => {
  return {
    type: FETCH_PRODUCTS_ERROR,
    payload: error,
  };
};

productReducer.js

const initialState = {
  loading: true,
  products: [],
  error: "",
};

const productReducer = (state = initialState, action) => {
  switch (action.type) {
    case "FETCH_PRODUCTS_REQUESTS":
      return {
        ...state,
        loading: true,
      };

    case "FETCH_PRODUCTS_SUCCESS":
      return {
        loading: false,
        products: action.payload,
        error: "",
      };

    case "FETCH_PRODUCTS_ERROR":
      return {
        loading: false,
        products: [],
        error: action.payload,
      };
    default:
      return state;
  }
};

export default productReducer;

Root Reducer

import { combineReducers } from "redux";

import productReducer from "./productReducer";

const rootReducer = combineReducers({
  rootProduct: productReducer,
});

export default rootReducer;

One Answer

You can do a quick check if there is data coming from your axios by doing this (it will prevent any undefined or null values)

dispatch(fetchProductsSuccess(response.data || 'no data'));

Also you should return your state in the reducer as follows:

case "FETCH_PRODUCTS_SUCCESS":
      return {
        ...state,
        loading: false,
        products: action.payload,
        error: "",
      };

    case "FETCH_PRODUCTS_ERROR":
      return {
        ...state,
        loading: false,
        products: [],
        error: action.payload,
      };

Your

itemsProduct: state.rootProduct.products.filter(
      (prod) => prod.id == ownProps.match.params.id
    ),

may return an empty array meaning you will not be able to retrieve that object in your view

<h4>{this.props.itemsProduct[0].name}</h4>

Answered by Eugen Sunic on March 1, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP