1

I am fetching data from API endpoint. I have made action and reducer for VenueList.js

venueAction.js:

import { FETCH_VENUES } from './types';
import axios from 'axios';

export const fetchVenues = () => dispatch => {
    axios.get(`API_ENDPOINT`)
    .then( venues => 
        dispatch({
            type: FETCH_VENUES,
            payload: venues
        })
    )
    .catch( error => {
        console.log(error);
    });
};

venueReducer.js:

import { FETCH_VENUES } from '../actions/types';

const initialState = {
    items: []
}

export default function (state = initialState, action) {
    switch (action.type) {
        case FETCH_VENUES:
            return {
                ...state,
                items: action.payload
            };
        default:
            return state;
    }
}

VenueList.js:

import React, { Component } from 'react';
import { View } from 'react-native';
import { connect } from 'react-redux';
import { fetchVenues } from '../actions/venueAction';

class VenueList extends Component {

    componentWillMount (){
        this.props.fetchVenues();
    }

    render() {
        // if(this.props.venues.data){
            console.log(this.props.venues.data[0].highlight)
        // }

        return (
            <View style={styles.container}>

            </View>
        );
    }
}  

const styles = StyleSheet.create({
    container: {
       flex: 1
    },

});

const mapStateToProps = state => ({
    venues: state.venues.items
})

export default connect (mapStateToProps, { fetchVenues })(VenueList);

If I uncomment the if statement in VenueList.js then it shows the this.props.venues.data[0].highlight data but if there is no if statement then it throws error. How can I display data after getting the data from API endpoint. Initially during fetch venues are undefined and after 1 sec the data is filled in using api endpoint. So if I want to display

<Text>{this.props.venues.data[0].highlight}</Text> it throws error Do I need to add if statements at each sections. How can I overcome this issue ?

Screenshots:

if I comment the if statement: enter image description here

Initially venues is empty array and after fetch the data is filled in see below: enter image description here

fun joker
  • 1,717
  • 6
  • 31
  • 52
  • 1
    You should check this question https://stackoverflow.com/questions/47392910/use-componentwillmount-or-componentdidmount-lifecycle-functions-for-async-reques/47393005#47393005 – Shubham Khatri Sep 26 '18 at 15:30
  • @ShubhamKhatri I still get an empty array if I change to componentDidMount() ? Why so? – fun joker Sep 26 '18 at 15:32
  • If you read the complete answer, it will tell you that the response is available only after the render has happened and hence you should be initialising the value correctly or checking for undefined value before using it in render – Shubham Khatri Sep 26 '18 at 15:34
  • @ShubhamKhatri So everytime I should check if `this.props.venues` is present or not and after that only I should display the data am I right ? But everytime I want to display some data from API endpoint I always need to do this,props.venues ? display my data : "Not loaded" – fun joker Sep 26 '18 at 15:36
  • 1
    Yes, you are right. You need to do it if you are getting data from API call – Shubham Khatri Sep 26 '18 at 15:38

1 Answers1

1

You can ensure it's defined before trying to access it, and render some other text while it's loading.

{this.props.venues ? this.props.venues.data[0].highlight : "Text to display when not loaded"}
ᴘᴀɴᴀʏɪᴏᴛɪs
  • 7,169
  • 9
  • 50
  • 81
  • @panayiotis Everytime I need to check if `this.props.venues` is not null ? Is there anyother way ? – fun joker Sep 26 '18 at 15:29
  • Well the only other option is to pre-initialise it to something but then you need to make sure it has `data` array with at least one element and a `highlight` property. In theory your web request could take 2 seconds, what should React display in the meantime? There's also [lodash .get](https://lodash.com/docs/4.17.10#get) as a small helper to make this easier to write. – ᴘᴀɴᴀʏɪᴏᴛɪs Sep 26 '18 at 15:33