Reputation: 187
In my react app I am using API calls which should be authenticated by a token. so the first call is for getToken and then storing token in the session, but whenever I start my project it always throws an error on first run it(the error on the title)but if I refresh it, everything works. Can somebody explain to me what I am missing is this a problem of Async Calls?
Below are some part of my code
1). This is where I call token and other required API for my page during load:
componentDidMount() {
this.props.getToken('[email protected]','react007zxt');
//sessionStorage.setItem('jwtToken', this.props.token);
this.props.fetchStates();
this.props.fetchVenues();
}
2). This is the action where I call fetch API:
import {
FETCH_STATES,
FETCH_VENUES
} from '../actions/types';
const token = sessionStorage.getItem('jwtToken');
const postheaders={
'Content-Type': 'application/x-www-form-urlencoded'
};
export const getToken = (username,password) => dispatch=>{
fetch('http://localhost:8001/api/getToken',{
method: 'POST',
headers: postheaders,
body:JSON.stringify({username,password})
})
.then(res => res.json())
.then(token =>{
let str=JSON.stringify(token.token).replace(/"/g,"");
sessionStorage.setItem('jwtToken',str);
});
};
export const fetchStates = () => dispatch => {
fetch(`http://localhost:8001/api/states?token=${token}`)
.then(res => res.json())
.then(states => dispatch({
type: FETCH_STATES,
payload: states
}));
};
export const fetchVenues=()=>dispatch=>{
fetch('http://localhost:8001/api/venues')
.then(res => res.json())
.then(venues => dispatch({
type: FETCH_VENUES,
payload: venues
})
);
};
3). Below is the part of render where I am using it and getting an error on the first run :
const stateItems = this.props.states.map(data => (
<option key={data.id} value = {data.state} > {data.state} </option>
));
));
const venueItems = this.props.venues.map(venue => (
<option key={venue.id} value = {venue.id} > {venue.college_name} </option>
));
Edit 1: Problem is with token getting set in session store which is not available for the first API calls of states and venues.
http://localhost:8001/api/states?token=null 400 (Bad Request)
Upvotes: 2
Views: 918
Reputation: 4537
On the first render, the api call is being made, so it's most likely that when you are trying to access this.props.states
it is undefined
or empty.
A conditional to check it's availability should work for you, something on the lines of this.props.states && this.props.states.map(..)
You'll have to make sure other things work fine if this doesn't render until this.props.states
gets populated with values.
Hope this helps :)
Upvotes: 3