Reputation: 3
I'm new and still learning and I've come across problem and I don't have enough knowledge to solve it.
I have API setup with Flask and route "/api/stats" returns array of data I want to display. I followed a tutorial but I have hard time implementing it into my code.
Logger shows "fetchDev" action start, then fetchDev calls action "startDevSearch" can see it in console, state isFetching in "startDevSearch" turns true from false and then I get "TypeError: "e is undefined" error and shortly after "Network Error". I sniffed traffic with Fiddler and the browser successfully makes request to "http://127.0.0.1/api/stats" and gets the response I dont know how to solve it. I dont want to be spoonfed but just tell me whats wrong and I will head from there, right now I'm clueless. Thanks alot
Actions.js:
import axios from "axios";
export const selectAd = (ad) => {
console.log("You clicked on ad: ", ad.id);
return {
type: "AD_SELECTED",
payload: ad
};
}
export let startDevSearch = () => {
return {
type: "Start_Dev_Search"
}
}
export let endDevSearch = (devsArray) => {
return {
type: "End_Dev_Search",
devsArray
}
}
export let fetchDev = () => {
let url = "http://127.0.0.1:5000/api/stats"
return (dispatch) => {
dispatch(startDevSearch())
return axios.get(url).then(
(response) => {
dispatch(endDevSearch(response.data))
},
(err) => {
console.log(err);
}
)
}
}
Reducer.js:
export let devsReducer = (state={isFetching : false, devsArray : []},action) => {
switch(action.type){
case 'Start_Dev_Search':
return {
isFetching : true
}
break;
case 'End_Dev_Search':
return{
isFetching : false,
devsArray : action.devsArray
}
break;
default:
return state;
}
}
Reducer index.js:
import {combineReducers} from 'redux';
import {devsReducer} from "./adsReducer";
const allReducers = combineReducers({
ads: devsReducer,
});
export default allReducers;
Container.js
import React, {Component} from "react";
import {connect} from "react-redux";
import {bindActionCreators} from 'redux';
import {selectAd} from "../actions/adsActions";
import {fetchDev} from "../actions/adsActions"
class AdsList extends Component {
componentWillMount() {
this.props.fetchDev();
}
renderList(ad) {
return (
<a key={ad.id} onClick={() => this.props.selectAd(ad)} className="list-group-item list-group-item-action flex-column align-items-start">
<div className="d-flex w-100 justify-content-between">
<h5 className="mb-1">{ad.text}</h5>
<small className="text-muted">{ad.date}</small>
</div>
</a>
)
}
render() {
if(this.props.isFetching == true) {
return <p>Loading</p>
}
else if (this.props.isFetching == false && this.props.devsArray.length >= 1) {
return (
<div>
{this.props.devsArray.map(this.renderList)}
</div>
);
}
}
}
function matchDispatchToProps(dispatch){
return bindActionCreators({selectAd: selectAd, fetchDev: fetchDev}, dispatch);
}
export default connect(null, matchDispatchToProps)(AdsList);
Component.js:
import React from "react";
import AdsList from "../containers/AdsList";
const App = () => {
return (
<div>
<AdsList/>
<hr />
</div>
);
};
export default App;
store.js:
import {createStore, combineReducers, applyMiddleware} from "redux";
import {createLogger} from 'redux-logger'
import thunk from "redux-thunk";
import allReducers from "./reducers";
export default createStore(
allReducers,
applyMiddleware(createLogger(), thunk)
);
index.js:
import {render} from "react-dom";
import React from "react";
import {Provider} from "react-redux";
import App from "./components/Main";
import store from "./store"
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("content"));
Upvotes: 0
Views: 1149
Reputation: 36
You must add a mapStateToProps method in your component and declare it as a parameter in your connect method ( where you have declared null).
Example : function mapStateToProps (state,props){ return( state variable: get the respective state variable ) }
Upvotes: 1