Reputation: 662
I'm loading data from an API using Redux & React. Despite successfully pulling the data and applying it to the state, it's throwing an error:
Uncaught TypeError: Cannot read property 'payload' of undefined.
This occurs after the FETCH_PRODUCT_LISTINGS_PENDING
action type in the console.
React Component:
import React from 'react';
import { connect } from 'react-redux';
import store from '../../../store';
import * as ProductListingActions from '../actions/ProductListingActions';
@connect((store) => {
return {
productListing: store.productListing.products
}
})
export default class ProductListingContainer extends React.Component {
constructor(data) {
super();
this.props = data;
this.props.dispatch(ProductListingActions.fetchProductListings());
}
render() {
return <div></div>;
}
}
Reducer:
import CookieHandler from '../../../modules/CookieHandler';
const cookieHandler = new CookieHandler;
export default function reducer(
state = {
products: [],
fetching: false,
fetched: false,
error: null
}, action) {
switch(action.type) {
case "FETCH_PRODUCT_LISTINGS_PENDING":
return {
...state,
fetching: true,
}
break;
case "FETCH_PRODUCT_LISTINGS_REJECTED":
return {
...state,
fetching: false,
error: action.payload
}
break;
case "FETCH_PRODUCT_LISTINGS_FULFILLED":
return {
...state,
fetching: false,
fetched: true,
products: action.payload.data.default
}
break;
}
return state;
}
Actions:
import Config from '../../../Config.js';
import store from '../../../store.js';
import axios from 'axios';
export function fetchProductListings() {
store.dispatch({
type: "FETCH_PRODUCT_LISTINGS",
payload: axios.get(Config.getConfigAPIUrl() + '/cartel/products')
})
}
Any help would be appreciated
Upvotes: 0
Views: 17022
Reputation: 11
I was recently using redux-toolkit
for fetching api, and I faced the same problem. When I checked the api result, I saw my payload value was undefined
.
I solved this problem by simply returning the result of my api data.
export const getPosts = createAsyncThunk("posts/getPosts", async ()=> {
const res = await axios.get(`${baseURL}/posts/1`)
return res.data;
});
Upvotes: 0
Reputation: 20614
You're dispatching a call to dispatch, rather than dispatching an object.
this.props.dispatch(ProductListingActions.fetchProductListings());
function fetchProductListings() {
store.dispatch({
type: "FETCH_PRODUCT_LISTINGS",
payload: axios.get(Config.getConfigAPIUrl() + '/cartel/products')
})
}
if you inline this:
this.props.dispatch(
store.dispatch({
type: "FETCH_PRODUCT_LISTINGS",
payload: axios.get(Config.getConfigAPIUrl() + '/cartel/products')
})
)
Your action creator should not be calling dispatch, it should just return an action:
export function fetchProductListings() {
return {
type: "FETCH_PRODUCT_LISTINGS",
payload: axios.get(Config.getConfigAPIUrl() + '/cartel/products')
}
}
Keep in mind though, axios.get
is asynchronous, so payload
will be promise. You may want to consider adding redux-thunk
to handle the fulfillment of the promise.
Upvotes: 5