KK28
KK28

Reputation: 23

react destructuring variable got undefined

I am new to react. My problem is that my variables keep saying that it is undefined. What I am trying to do is to display those variable but fail to destructure it. A filter function is executed and return a single tour. The data is successfully retrieved. By destructuring this, some variable contains an array can not be displayed. Does anyone know how to fix this?

TypeError: Cannot read property '0' of undefined

My data looks like this.

[
  { 
    "_id": "12345",
    "name": "I am first tour",
    "startLocation": {
       description: "USA",
       type: "point"
    },
    "startDates": [
      "2021-06-19T09:00:00.000Z",
      "2021-07-20T09:00:00.000Z",
    ],
    "imageUrl": [
      "https://something1.jpg",
      "https://something2.jpg",
      "https://something3.jpg",
    ],
  },
  //.....rest data
]
import React, { Component } from 'react';
import './Tour.css';
import { connect } from 'react-redux';

class Tour extends Component {
constructor(props) {
    super(props)
        this.findSingletour = this.findSingletour.bind(this);
    }

    findSingletour = (tourId) => {
        const notYetFilterTours = this.props.tours.tourState.data;
        let filtered = [];

        if (notYetFilterTours) {
            filtered = notYetFilterTours.find((tour) => {
                if (tour.id === tourId) {
                    return filtered;
                }
                return filtered;
            });
        }
        return filtered;
    };
        
    render() {
    const tourId = this.props.match.params._id;
    let SingleTour = this.findSingletour(tourId);
     
        const {
            name,
            startLocation,
            startDates,
            imageUrl
            } = SingleTour;

        return (
            <div>
                <span>{name}</span> // successfully rendered
                <span>{startLocation[0]}</span> // undefined
                <span>{startDates[0]}</span> // undefined
                <span>{imageUrl[0]}</span> // undefined
            </div>
        )
    }
}

const mapStateToProps = (state) => ({
    tours: state.tourContainer,
});

export default connect(
    mapStateToProps,
)(Tour);

Upvotes: 1

Views: 1027

Answers (2)

Vivek V Dwivedi
Vivek V Dwivedi

Reputation: 2615

You can provide default values, and it is generally a good idea to have sensible defaults in case data is not loaded and UI is rendered.

So something like this would prevent such errors:

const {
    name = '',
    startLocation = [],
    startDates = [],
    imageUrl = ''
} = SingleTour;

Now if your UI renders and tries to get 0 of startLocation, it won't fail. It will of course find nothing, and display nothing except the UI skeleton, but the app will not error out.

Upvotes: 1

Or Assayag
Or Assayag

Reputation: 6336

Need to do validation just in case:

class Tour extends Component {
    // some code
    render() {
     
        const {
            name,
            startLocation,
            startDates,
            imageUrl
            } = SingleTour;

        return (
            <div>
                <span>{name}</span> // successfully rendered
                <span>{startLocation && startLocation.length > 0 ? startLocation[0] : ''}</span> // undefined
                <span>{startDates && startDates.length > 0 ? startDates[0] : ''}</span> // undefined
                <span>{imageUrl && imageUrl.length > 0 ? imageUrl[0] : ''}</span> // undefined
            </div>
        )
    }
}

Upvotes: 1

Related Questions