Sharad Mishra
Sharad Mishra

Reputation: 187

React-Redux: this.props.data.map is not a function error

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

Answers (1)

Aseem Upadhyay
Aseem Upadhyay

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

Related Questions