Strange issue when making requests/displaying data on React (Axios, React, Redux) - javascript

I'm trying to make a personal app and I'm running into some issues with the requests, nothing to do with the API.
The results of the request returns this JSON: https://pastebin.com/raw/vpdq2k6S
My code:
class Home extends Component {
componentDidMount() {
this.props.getTrending();
}
render() {
const { trending } = this.props.trending;
console.log(trending);
const Card = (props) => (
<Panel {...props} bordered header='Card title'>
{trending.results.map((i) => (
<React.Fragment key={i.id}>
<h6>{i.title}</h6>
</React.Fragment>
))}
</Panel>
);
return (
<div className='Home'>
<FlexboxGrid justify='center'>
<Card />
</FlexboxGrid>
</div>
);
}
}
export default connect(
(state) => {
return {
trending: state.trending,
};
},
{ getTrending }
)(Home);
My action:
import { GET_TRENDING } from "../types";
import axios from "axios";
export const getTrending = () => async (dispatch) => {
const res = await axios.get(
`https://api.themoviedb.org/3/movie/popular?api_key=KEY&language=en-US&page=1`
);
dispatch({
type: GET_TRENDING,
payload: res.data,
});
};
My reducer:
import { GET_TRENDING } from "../types";
const initialState = {
trending: [],
loading: true,
};
export default function trendingReducer(state = initialState, action) {
switch (action.type) {
case GET_TRENDING:
return {
...state,
trending: action.payload,
loading: false,
};
default:
return state;
}
}
Ignore the Card constant etc, that's related to an UI components library. You can see from the code that I'm logging the results of 'trending'. But I'm getting an empty array but here's the strange part:
If I change my map function from mapping through "trending.results" to "trending" and I refresh then the console returns an empty array and another array which is the correct one. If I change it back to "trending.results" then React auto-reloads the page returns me the correct array two times and it displays the data on the app but if I refresh the page without changing anything on the code then it goes back to showing an empty array and an error that says "cannot read property map of undefined" obviously cause somehow I'm not getting the correct data.
Anyone ever had this before? It makes absolutely no sense at all or if so then can someone guide me on how to solve this? I tried shutting down the React server completely and restarting it that wouldn't solve it. My brain is frozen (I can record a clip if required)

The answer is pretty simple. All you have to do is first getting the array from the api and then mapping through it. trending.results is not set so the error is shown. Cannot read property map of undefined
Go with a ternary operator:
{trending.results && trending.results.map((i) => (
<React.Fragment key={i.id}>
<h6>{i.title}</h6>
</React.Fragment>
))}

try this way.
export const getTrending = () => async (dispatch) => {
const res = await axios.get(
`https://api.themoviedb.org/3/movie/popular?api_key=KEY&language=en-US&page=1`
);
dispatch({
type: GET_TRENDING,
payload: res.data.results,
});
};
const Card = (props) => (
<Panel {...props} bordered header='Card title'>
{trending && trending.map((i) => (
<React.Fragment key={i.id}>
<h6>{i.title}</h6>
</React.Fragment>
))}
</Panel>
);

Related

React redux state is undefined on first render despite of initlizedState

Redux state is undefined in first render and I returned the initilizedState = {} in my reducer
store.js
const store = createStore(
rootReducer,
compose(
applyMiddleware(thunk),
window.devToolsExtension ? window.devToolsExtension() : (f) => f
)
)
export default store
rootReducer.js
const rootReducer = combineReducers({
search: searchReducer,
product: productReducer,
})
export default rootReducer
reducer.js
const initialState = {}
const productReducer = (state = initialState, action) => {
const { type, payload } = action
switch (type) {
case PRODUCTS_ALL:
console.log('reducer')
return { ...state, items: payload }
default:
return state
}
}
export default productReducer
action.js
const products = axios.create({
baseURL: 'http://localhost:8001/api/products',
})
export const allProducts = () => async (dispatch) => {
console.log('fetching')
await products.get('/').then((res) => {
dispatch({
type: PRODUCTS_ALL,
payload: res.data,
})
})
}
And although I used connect() in my feed container
Feed.js
function Feed({ allProducts, product }) {
const [productItems, setProductItems] = useState()
const [loading, setLoading] = useState(false)
React.useEffect(() => {
allProducts()
console.log(product)
}, [])
return (
<div className='feed__content'>
{loading ? (
<Loader
type='Oval'
color='#212121'
height={100}
width={100}
/>
) : (
<div className='feed__products'>
<div className='feed__productsList'>
{product.map((product) => {
return (
<Product
name={product.name}
image={product.image}
price={product.price}
/>
)
})}
</div>
</div>
)}
</div>
)
}
const mapStateToProps = (state) => ({
product: state.product.items,
})
const mapDispatchToProps = (dispatch) => {
return {
allProducts: () => dispatch(allProducts()),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Feed)
if you look at the data on the console you will see undefined but if I add a useEffect dependency it will create a loop , and the first of them is undefined and the rest are the data that I want.
because of this problem when I want to render products with map , it throws an error that said can't map undefiend .
How can I solve this problem
Joel Jaimon code worked well .
and in my code I added
const initialState = {
items: []
}
according to #Andrew and product?.map so my code works well now.
In Feed.js, you aren't getting the entire slice of state. You are trying to access the key item inside.
const mapStateToProps = (state) => ({
product: state.product.items,
})
Change your initialState to include that key and your code should be fine
const initialState = {
items: []
}
A/c to your code you're trying to make an async action in redux. You should use redux-saga or redux-thunk for this.
But you can achieve your output in the following way, without using redux-saga or thunk.
Modify your code in the following way:
Feed.js
function Feed({ allProducts, product }) {
// Set loading to true inititally
const [loading, setLoading] = useState(true);
React.useEffect(() => {
// Make your api call here once its complete and you get a res,
// dispatch the referred action with response as payload.
(async () => {
const products = axios.create({
baseURL: "http://localhost:8001/api/products",
});
const {data} = await products.get("/");
allProducts(data);
})()
// This call is only made when you load it for the first time, if it
// depends
// on something add that dependencies in the dependency array of //
// useEffect.
}, []);
// once store is updated with the passed payload. Set loading to
// false.
React.useEffect(() => {
if(product){
setLoading(false);
}
}, [product])
return (
<div className="feed__content">
{loading ? (
<Loader type="Oval" color="#212121" height={100} width={100} />
) : (
<div className="feed__products">
<div className="feed__productsList">
{product.map((product) => {
return (
<Product
name={product.name}
image={product.image}
price={product.price}
/>
);
})}
</div>
</div>
)}
</div>
);
}
const mapStateToProps = ({product}) => ({
product: product?.items,
});
// here we have a payload to pass
const mapDispatchToProps = (dispatch) => {
return {
allProducts: (payload) => dispatch(allProducts(payload)),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Feed);
Action
export const allProducts = (payload) => ({
type: "PRODUCTS_ALL",
payload,
});
Reducer
const productReducer = (state = initialState, action) => {
const { type, payload } = action
switch (type) {
case "PRODUCTS_ALL":
return { ...state, items: payload }
default:
return state
}
}
export default productReducer
Problem statement: I would be giving you three really best methods, in order to solve it, the problem appears when redux is transferring states to the components, so it seems that the render is faster than the response of props to the component.
So, when you have props undefined by their value your application crashes.
note: I will be taking a general example and will show you how to avoid this error.
For example, I have a component in which I want to render the data from the redux response (with mapPropsToState), what I need to do is only to check it for undefined and then if it is undefined we need to use the conditional (ternary) operator for if and else statements.
//suppose you will get an address object from api ,which will contain city ,area ,street ,pin code etc
// address={} intially address is a blank object
render(){
return(
(typeof address.area!='undefined')?
<div>
<div>{address.city}</div>
<div>{address.street}</div>
<div>{address.pin_code}</div>
<div>{address.area}</div>
</div>
:<div>loading....</div>
)
}
And another way is to simply use the package of loadash in loadash you can achieve the same by calling the function "isUndefined"
you can also use it in the inputFields likewise
<FloatingLabel label="Username">
<Form.Control
type="input"
placeholder=" "
name="username"
value={props.username}
defaultValue={_.isUndefined(props.userEditResponse)?'':props.userEditResponse.username}
required
onChange={(e)=>onInputchange(e)}
/>
</FloatingLabel>
//note: you can also use (typeof props.userEditResponse!='undefined')?'do somthing':'leave it'
loadash installation:
npm i lodash
then in your component import the the below line and then you can use it, the way i used in the above example.
import _ from 'lodash'
note: the answer was just to give you an idea and this was really a panic problem that is why I shared it with you guys, it might help many of you, you can use a similar way in different situations. thanks!
furtherMore your can work with ?.:
The ?. operator is like the . chaining operator, except that instead of causing an error if a reference is nullish (null or undefined), the expression short-circuits with a return value of undefined. When used with function calls, it returns undefined if the given function does not exist.
This results in shorter and simpler expressions when accessing chained properties when the possibility exists that a reference may be missing. It can also be helpful while exploring the content of an object when there's no known guarantee as to which properties are required.
{ props.rolesListSuccessResponse?.permissions.map((list,index) => (
<div className="mb-3 col-md-3" key={index}>
<Form.Check
type={'checkbox'}
id={list.name}
label={list.name.charAt(0).toUpperCase()+list.name.slice(1)}
/>
</div>
))}

Making an axios get request and using React useState but when logging the data it still shows null

When I make a request to an API and setting the state to the results from the Axios request it still shows up null. I am using React useState and setting the results from the request and wanting to check to see if its coming through correctly and getting the right data its still resulting into null. The request is correct but when I use .then() to set the state that is the issue I am having.
Below is the component that I am building to make the request called Details.js (first code block) and the child component is the DetailInfo.js file (second code block) that will be displaying the data. What am I missing exactly or could do better when making the request and setting the state correctly display the data?
import React, {useEffect, useState} from 'react';
import { Col, Container, Row } from 'react-bootstrap';
import axios from 'axios';
import { getCookie } from '../utils/util';
import DetailInfo from '../components/DetailInfo';
import DetailImage from '../components/DetailImage';
const Details = () => {
const [ countryData, setCountryData ] = useState(null);
let country;
let queryURL = `https://restcountries.eu/rest/v2/name/`;
useEffect(() => {
country = getCookie('title');
console.log(country);
queryURL += country;
console.log(queryURL);
axios.get(queryURL)
.then((res) => {
console.log(res.data[0])
setCountryData(res.data[0]);
})
.then(() => {
console.log(countryData)
}
);
}, [])
return (
<>
<Container className="details">
<Row>
<Col sm={6}>
<DetailImage />
</Col>
<Col sm={6}>
<DetailInfo
name={countryData.name}
population={countryData.population}
region={countryData.region}
subRegion={countryData.subRegion}
capital={countryData.capital}
topLevelDomain={countryData.topLevelDomain}
currencies={countryData.currencies}
language={countryData.language}
/>
</Col>
</Row>
</Container>
</>
)
}
export default Details;
The child component below......
import React from 'react';
const DetailInfo = (props) => {
const {name, population, region, subRegion, capital, topLevelDomain, currencies, language} = props;
return (
<>detail info{name}{population} {region} {capital} {subRegion} {topLevelDomain} {currencies} {language}</>
)
}
export default DetailInfo;
Ultimately, the problem comes down to not handling the intermediate states of your component.
For components that show remote data, you start out in a "loading" or "pending" state. In this state, you show a message to the user saying that it's loading, show a Spinner (or other throbber), or simply hide the component. Once the data is retrieved, you then update your state with the new data. If it failed, you then update your state with information about the error.
const [ dataInfo, setDataInfo ] = useState(/* default dataInfo: */ {
status: "loading",
data: null,
error: null
});
useEffect(() => {
let unsubscribed = false;
fetchData()
.then((response) => {
if (unsubscribed) return; // unsubscribed? do nothing.
setDataInfo({
status: "fetched",
data: response.data,
error: null
});
})
.catch((err) => {
if (unsubscribed) return; // unsubscribed? do nothing.
console.error('Failed to fetch remote data: ', err);
setDataInfo({
status: "error",
data: null,
error: err
});
});
return () => unsubscribed = true;
}, []);
switch (dataInfo.status) {
case "loading":
return null; // hides component
case "error":
return (
<div class="error">
Failed to retrieve data: {dataInfo.error.message}
</div>
);
}
// render data using dataInfo.data
return (
/* ... */
);
If this looks like a lot of boiler plate, there are useAsyncEffect implementations like #react-hook/async and use-async-effect that handle it for you, reducing the above code to just:
import {useAsyncEffect} from '#react-hook/async'
/* ... */
const {status, error, value} = useAsyncEffect(() => {
return fetchData()
.then((response) => response.data);
}, []);
switch (status) {
case "loading":
return null; // hides component
case "error":
return (
<div class="error">
Failed to retrieve data: {error.message}
</div>
);
}
// render data using value
return (
/* ... */
);
Because state only update when component re-render. So you should put console.log into useEffect to check the new value:
useEffect(() => {
country = getCookie('title');
console.log(country);
queryURL += country;
console.log(queryURL);
axios.get(queryURL).then(res => {
console.log(res.data[0]);
setCountryData(res.data[0]);
});
}, []);
useEffect(() => {
console.log(countryData);
}, [countryData]);
useState does reflecting its change immediately.
I think that it would be probably solved if you set countryData to second argument of useEffect.
useEffect(() => {
country = getCookie('title');
console.log(country);
queryURL += country;
console.log(queryURL);
axios.get(queryURL)
.then((res) => {
console.log(res.data[0])
setCountryData(res.data[0]);
})
.then(() => {
console.log(countryData)
}
);
}, [countryData])
The issue is, as samthecodingman, pointed out, an issue of intermediate data. Your component is being rendered before the data is available, so your child component needs to re-render when its props change. This can be done via optional chaining, an ES6 feature.
import React, { useEffect, useState } from "react";
import DetailInfo from "./DetailInfo";
import { Col, Container, Row } from "react-bootstrap";
import axios from "axios";
const Details = () => {
const [countryData, setCountryData] = useState({});
let country = "USA";
let queryURL = `https://restcountries.eu/rest/v2/name/`;
useEffect(() => {
console.log(country);
queryURL += country;
console.log(queryURL);
axios
.get(queryURL)
.then((res) => {
console.log(res.data[0]);
setCountryData(res.data[0]);
})
.then(() => {
console.log(countryData);
});
}, []);
return (
<Container className="details">
<Row>
<Col sm={6}>
<DetailInfo
name={countryData?.name}
population={countryData?.population}
region={countryData?.region}
subRegion={countryData?.subRegion}
capital={countryData?.capital}
language={countryData?.language}
/>
</Col>
<Col sm={6}></Col>
</Row>
</Container>
);
};
export default Details;
Checkout my Codesandbox here for an example.

How to instantly display data after an API call in react hooks

I don't understand why the second line, which reads data from the props, is not displayed as instantly as the first, i would like them to be displayed instantly
I update the state when a button is clicked, which calls api, data is coming in, the state is updating, but the second line requires an additional press to display
How to display both lines at once after a call? What's my mistake?
I'm using react hooks, and i know that required to use useEffect for re-render component, i know, that how do work asynchronous call,but i'm a little confused, how can i solve my problem, maybe i need to use 'useDeep effect' so that watching my object properties, or i don't understand at all how to use 'useEffect' in my situation, or even my api call incorrectly?
I have tried many different solution methods, for instance using Promise.all, waiting for a response and only then update the state
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./test";
ReactDOM.render(<App />, document.getElementById("root"));
app.js
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
const useDataApi = (initialState) => {
const [state, setState] = useState(initialState);
const stateCopy = [...state];
const setDate = (number, value) => {
setState(() => {
stateCopy[number].date = value;
return stateCopy;
});
};
const setInfo = async () => {
stateCopy.map((item, index) =>
getFetch(item.steamId).then((res) => setDate(index, res.Date))
);
};
const getFetch = async (id) => {
if (id === "") return;
const requestID = await fetch(`https://api.covid19api.com/summary`);
const responseJSON = await requestID.json();
console.log(responseJSON);
const result = await responseJSON;
return result;
};
return { state, setState, setInfo };
};
const Children = ({ data }) => {
return (
<>
<ul>
{data.map((item) => (
<li key={item.id}>
{item.date ? item.date : "Not data"}
<br></br>
</li>
))}
</ul>
</>
);
};
const InfoUsers = ({ number, steamid, change }) => {
return (
<>
<input
value={steamid}
numb={number}
onChange={(e) => change(number, e.target.value)}
/>
</>
);
};
function App() {
const usersProfiles = [
{ date: "", id: 1 },
{ date: "", id: 2 }
];
const profiles = useDataApi(usersProfiles);
return (
<div>
<InfoUsers number={0} change={profiles.setID} />
<InfoUsers number={1} change={profiles.setID} />
<button onClick={() => profiles.setInfo()}>Get</button>
<Children data={profiles.state} loading={profiles} />
</div>
);
}
export default App;
To get the data, just click GET
In this example, completely removed useEffect, maybe i don’t understand how to use it correctly.
P.s: Sorry for bad english
You don't need stateCopy, as you have it in the callback of the setState:
const setInfo = async () => {
// we want to update the component only once
const results = await Promise.all(
state.map(item => getFetch(item.steamId))
);
// 's' is the current state
setState(s =>
results.map((res, index) => ({ ...s[index], date: res.Date })
);
};

React/Redux Reset State Upon Route Change

EDIT: In the code I show below the user NEVER sees the message because the state is reset. The screenshot is merely an example to show the message that I'd like to get displayed.
Current State: Upon successful add to the database, "Facility created successfully" message NEVER shows. However, if I remove the reset code, when the user navigates away from the page and comes back, the message persists. The root cause of this is that my state in Redux has a "success" setting upon successful add to the database. If I do a reset upon the success message, the user never sees it because the state is reset to an empty object.
Ideal State: User adds facility to database, success message comes back via Redux state and message shows. The page refreshes showing the newly added facility. The user navigates away from the page and then the Redux state is reset.
I've tried libraries from React to detect unmount in addition to using a cleanup function in useEffect to no avail.
I will list my code below and appreciate any feedback or insights. Note that some irrelevant code has been trimmed for the sake of space.
FacilityAdminScreen.js (component)
import React, { useState, useEffect } from "react";
import { Form, Row, Button, Col } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import Message from "../components/Message";
import Loader from "../components/Loader";
import { chunk } from "lodash";
import FacilityCard from "../components/FacilityCard";
import { createFacility, getFacilityAllBasicInfo } from "../actions/facilityActions";
import { FACILITY_ADD_TO_DATABASE_RESET } from "../constants/facilityConstants";
const FacilityAdminScreen = ({ match }) => {
// State for form information
const [name, setName] = useState("");
const [streetAddress1, setStreetAddress1] = useState("");
const [streetAddress2, setStreetAddress2] = useState("");
const [city, setCity] = useState("");
const [state, setState] = useState("");
const [zip, setZip] = useState("");
const dispatch = useDispatch();
// List of facilities for populating page
const facilityAllBasicInfo = useSelector(state => state.facilityAllBasicInfo);
const { loading, error } = facilityAllBasicInfo;
const facilities = chunk(facilityAllBasicInfo.facilities, 2);
// Response upon adding facility to database
const facilityAddToDatabase = useSelector(state => state.facilityAddToDatabase);
const {
loading: loadingCreate,
error: errorCreate,
success: successCreate,
} = facilityAddToDatabase;
const submitHandler = e => {
e.preventDefault();
// Attempt to create the facility
dispatch(
createFacility({
company: match.params.companyId,
name,
streetAddress1,
streetAddress2,
city,
state,
zip,
})
);
};
useEffect(() => {
// Get all facilities for company
dispatch(getFacilityAllBasicInfo(match.params.companyId));
// If facility created successfully, reset all form state
if (successCreate) {
dispatch({ type: FACILITY_ADD_TO_DATABASE_RESET });
setName("");
setStreetAddress1("");
setStreetAddress2("");
setCity("");
setState("");
setZip("");
}
}, [dispatch, successCreate, match.params.companyId]);
return (
<>
<Row>
<Col md={8}>
<h1>Facilities</h1>
<h6>Click facility name for detailed information</h6>
{loading ? (
<Loader />
) : error ? (
<Message variant="danger">{error}</Message>
) : (
<>
{facilities.map((facilityArray, i) => (
<Row className="mb-3" key={i}>
{facilityArray.map((facility, i) => (
<Col md={6} key={i}>
<FacilityCard
key={facility._id}
companyId={match.params.companyId}
id={facility._id}
name={facility.name}
streetAddress1={facility.streetAddress1}
streetAddress2={facility.streetAddress2}
city={facility.city}
state={facility.state}
zip={facility.zip}
isActive={facility.isActive}
/>
</Col>
))}
</Row>
))}
</>
)}
</Col>
<Col md={4}>
<h1>Add Facility</h1>
{loadingCreate && <Loader />}
{errorCreate && <Message variant="danger">{errorCreate}</Message>}
{successCreate && (
<Message variant="success">Facility created successfully</Message>
)}
<Form onSubmit={submitHandler}>
{/*Trimmed code here for the sake of space */}
</Form>
</Col>
</Row>
</>
);
};
export default FacilityAdminScreen;
Reducers for BOTH getting the list of facilities and adding to database:
export const facilityAllBasicInfoReducer = (state = { facilities: [] }, action) => {
switch (action.type) {
case FACILITY_ALL_BASIC_INFO_REQUEST:
return { loading: true };
case FACILITY_ALL_BASIC_INFO_SUCCESS:
return { loading: false, facilities: action.payload };
case FACILITY_ALL_BASIC_INFO_FAIL:
return { loading: false, error: action.payload };
default:
return state;
}
};
export const facilityAddToDatabaseReducer = (state = {}, action) => {
switch (action.type) {
case FACILITY_ADD_TO_DATABASE_REQUEST:
return { loading: true };
case FACILITY_ADD_TO_DATABASE_SUCCESS:
return { loading: false, success: true, facility: action.payload };
case FACILITY_ADD_TO_DATABASE_FAIL:
return { loading: false, error: action.payload };
case FACILITY_ADD_TO_DATABASE_RESET:
return {};
default:
return state;
}
};
I don't think that your implementation of a cleanup function within useEffect that you copied in above is the right way to do it. The issue you are having is that the dispatch to reset the state is fired off straight after success becomes true.
I think what you are looking for is a way to use componentWillUnmount using Hooks, so that when you navigate away from the page and the component is destroyed it fires off an action that modifies the state the way you want.
The return statement on useEffect does this. Whatever you include in the return statement will be fired off when the component unmounts.
useEffect(() => {
dispatch(//action to add facility);
return () => {
dispatch(//action to modify state when component unmounts);
};
}, [dispatch]);
Using the above, when you navigate back to the page success will again be false.
Hopefully this helps.

My reducer does not seem to modify the state in the store to allow my React view to render again

To begin, I should mention that I have followed this pattern I'm about to show you with two other sets of React components in my project.
For some reason it seems to not work and I have focused in on that either the #connect or the reducer is the problem. I've had several people look over this and I've attempted several different methods to solve this problem.
import classNames from 'classnames';
import SidebarMixin from 'global/jsx/sidebar_component';
import Header from 'common/header';
import Sidebar from 'common/sidebar';
import Footer from 'common/footer';
import AppList from '../components/lists';
import { connect } from 'react-redux'
import actions from 'redux/actions';
import { VisibilityFilters } from 'redux/actions/actionTypes';
#connect((state) => state)
class AppContainer extends React.Component {
constructor(props) {
super(props)
}
componentWillMount() {
this.props.dispatch(actions.getUnconsidered(1));
this.props.dispatch(actions.getConsidered(3));
this.props.dispatch(actions.getInterviews(4));
this.props.dispatch(actions.getOffers(2));
}
This right here is dispatching four actions to fetch data for the application. We are using Redux Thunk middleware to deal with the async problems associated with making these Ajax requests.
I have found that the data from all of these Ajax calls is reaching the reducer.
render() {
console.log("AppContainer state", this.props);
This console.log should log twice... once empty during the first render and again when the state changes after the reducers which should show the state with my data mapped to the props because of the #connect.
I'm fairly certain of this because of my other views that I've done.
return (
<div>
<Container id='body'>
<Grid>
<Row>
<Col md={3}>
<AppList data={this.props.unconsidered}/>
</Col>
<Col md={3}>
<AppList data={this.props.considered} />
</Col>
<Col md={3}>
<AppList data={this.props.interviews} />
</Col>
<Col md={3}>
<AppList data={this.props.offers} />
</Col>
</Row>
</Grid>
</Container>
</div>
)
}
}
#SidebarMixin
export default class extends React.Component {
render() {
const dispatch = this.props.dispatch
var classes = classNames({
'container-open': this.props.open
})
return (
<Container id='container' className={classes}>
<Sidebar />
<Header />
<AppContainer />
<Footer />
</Container>
)}
}
This next code block is my action creator file.
import axios from 'axios';
import {GET_UNCONSIDERED,
GET_CONSIDERED,
GET_INTERVIEWS,
GET_OFFERS } from './actionTypes';
function getUnconsidered(jobID){
console.log('getUnconsidered Actions')
return dispatch => axios.get('/user/employer/appsbystatus?jobID='+jobID+'&status=unconsidered')
.then(
payload => dispatch({ type: GET_UNCONSIDERED, payload})
)
.catch(resp => console.log("Error fetching unconsidered", resp));
}
function getConsidered(jobID){
return dispatch => axios.get('/user/employer/appsbystatus?jobID='+jobID+'&status=considered')
.then(
payload => dispatch({ type: GET_CONSIDERED, payload})
);
}
function getInterviews(jobID){
return dispatch => axios.get('/user/employer/appsbystatus?jobID='+jobID+'&status=interviews')
.then(
payload => dispatch({ type: GET_INTERVIEWS, payload})
);
}
function getOffers(jobID){
return dispatch => axios.get('/user/employer/appsbystatus?jobID='+jobID+'&status=offers')
.then(
payload => dispatch({ type: GET_OFFERS, payload})
);
}
module.exports = {
getUnconsidered: getUnconsidered,
getConsidered: getConsidered,
getInterviews: getInterviews,
getOffers: getOffers
}
This here is my reducer file and where I believe my problem lies.
import {GET_UNCONSIDERED,
GET_CONSIDERED,
GET_INTERVIEWS,
GET_OFFERS } from '../actions/actionTypes';
function empdashboard(state = {}, action) {
console.log("state in dashboard reducer = ", state);
switch (action.type) {
case GET_UNCONSIDERED:
console.log("unconsidered:", action.payload)
const unconsidered = action.payload.data;
return Object.assign({}, state, {
unconsidered: unconsidered
});
case GET_CONSIDERED:
console.log("considered:", action.payload)
const considered = action.payload.data;
return Object.assign({}, state, {
considered: considered
});
case GET_INTERVIEWS:
console.log("interviews:", action.payload)
const interviews = action.payload.data;
return Object.assign({}, state, {
interviews: interviews
});
case GET_OFFERS:
console.log("offers:", action.payload)
const offers = action.payload.data;
return Object.assign({}, state, {
offers: offers
});
default:
return state;
}
}
module.exports = {
empdashboard: empdashboard
}
Honestly I'm under the impression that either my reducer is messed up or I'm having a bug with my #connect and it is not detecting the change in state to rerender my view.
Thanks for taking a look at this!

Categories