Tiberius
Tiberius

Reputation: 83

TypeError: Cannot destructure property 'title' of 'pres[0]' as it is undefined. (REACT)

I am new in the React world, I am working on a stupid project for get some experience and go deeper in the knowledge of this wonderful instrument, I am also new on stackoverflow and this is my very first post here, so I hope to don't make too many mistakes.

In my project I have a ProfileComponent, that looks like this:

    const ProfilePage = () => {

    const presentationUrl = baseUrl + 'presentation';

    const pres = useSelector((state) => state);
    const dispatch = useDispatch();

    const fetchPresentation = async () => {
        const response = await axios
            .get(presentationUrl)
            .catch((err) => {
                console.log('Err', err);
            });
        dispatch(addPresentation(response.data));
        console.log(response.data);
    }

    useEffect(() => {
        fetchPresentation();
    }, []);

    return (
        <div className="profile-page">

            { /* Profile page fixed image (left side) */}
            <div className="image-container col-md-5 col-sm-12">
                <div className="mask">
                </div>
                <div className="main-heading">
                    <h1>PR<span>O</span>FILE</h1>
                </div>
            </div>

            { /* Profile page content (right side) */}
            <div className="content-container col-md-7 col-sm-12">

                { /* PRESENTATION */}
                <ProfilePresentation />

                { /* Footer */}
                <Footer />
            </div>
        </div>
    );
    }

The PresentationComponent (which contain the ProfilePresentation const) looks like this:

    export const ProfilePresentation = () => {

    const pres = useSelector((state) => state.presentation.presentation);
    console.log(pres[0]);

    const { title, subtitle, image, description } = pres[0];

    return (
        <>
            { /* Presentation */}
            <div className="story clearfix">
                <h2 className="small-heading">{title}</h2>
                <div className="col-lg-11 col-lg-offset-1">
                    <div className="story-content clearfix">
                        <img alt="" src={image} className="col-xs-offset-1 col-sm-offset-0 col-sm-4 col-xs-10" />
                        <div className="col-sm-8 col-xs-12">
                            <h3>{subtitle}</h3>
                            <p>
                                {description}
                            </p>
                            <a href="#" className="hire-me">Hire Me</a>
                            <a href="#">Download Resume</a>
                        </div>
                    </div>
                </div>
            </div>
        </>
    );
}

This is my presentationActions.js:

import * as ActionTypes from '../constants/ActionTypes';

export const addPresentation = (presentation) => {
    return {
        type: ActionTypes.ADD_PRESENTATION,
        payload: presentation
    };
};

This is the ActionTypes.js:

export const ADD_PRESENTATION = 'ADD_PRESENTATION';

And this is my presentationReducer.js:

import * as ActionTypes from '../constants/ActionTypes';

const initialState = {
    presentation: [],
}

export const presentationReducer = (state = initialState, { type, payload }) => {
    switch (type) {
        case ActionTypes.ADD_PRESENTATION:
            return { ...state, presentation: payload };
        default:
            return state;
    }
}

I also have a local json-server, which is on, that contains a db.json file that looks like this:

{
  "presentation": [
        {
            "title": "PRESENTATION",
            "subtitle": "An Awesome Web delevoper on planet",
            "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent volutpat enim arcu, eget tempor nibh congue a. Maecenas faucibus sagittis nibh, in bibendum ex. Donec eu ornare augue, nec cursus arcu. Vivamus accumsan mauris nec nulla bibendum, et eleifend nisl tristique. Pellentesque fringilla lorem id nibh auctor sagittis. Suspendisse non nisl at velit malesuada bibendum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent volutpat enim arcu, eget tempor nibh congue a. Maecenas faucibus sagittis nibh, in bibendum ex. Donec eu ornare augue, nec cursus arcu. Vivamus accumsan mauris nec nulla bibendum, et eleifend nisl tristique. Pellentesque fringilla lorem id nibh auctor sagittis. Suspendisse non nisl at velit malesuada bibendum.",
            "image": "../../public/assets/images/dp.jpg"
        }
    ]
}

Now, this is what is happening:

  1. on the console.log in the ProfileComponent (in the fetchPresentation const) the result of the print in the console is working well and is returning the data as I wish, so, until that point everything is working well.
[{…}]
0:
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent volutpat enim arcu, eget tempor nibh congue a. Maecenas faucibus sagittis nibh, in bibendum ex. Donec eu ornare augue, nec cursus arcu. Vivamus accumsan mauris nec nulla bibendum, et eleifend nisl tristique. Pellentesque fringilla lorem id nibh auctor sagittis. Suspendisse non nisl at velit malesuada bibendum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent volutpat enim arcu, eget tempor nibh congue a. Maecenas faucibus sagittis nibh, in bibendum ex. Donec eu ornare augue, nec cursus arcu. Vivamus accumsan mauris nec nulla bibendum, et eleifend nisl tristique. Pellentesque fringilla lorem id nibh auctor sagittis. Suspendisse non nisl at velit malesuada bibendum."
image: "../../public/assets/images/dp.jpg"
subtitle: "An Awesome Web delevoper on planet"
title: "PRESENTATION"
__proto__: Object
length: 1
__proto__: Array(0)
  1. PresentationComponent: here I start having some troubles, if I comment out the 6th line you see in the code I've posted (const { title, subtitle, image, description } = pres[0];), my console.log on line 4 is working well and is returning the correct data I want:
{title: "PRESENTATION", subtitle: "An Awesome Web delevoper on planet", description: "Lorem ipsum dolor sit amet, consectetur adipiscing…Suspendisse non nisl at velit malesuada bibendum.", image: "../../public/assets/images/dp.jpg"}
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent volutpat enim arcu, eget tempor nibh congue a. Maecenas faucibus sagittis nibh, in bibendum ex. Donec eu ornare augue, nec cursus arcu. Vivamus accumsan mauris nec nulla bibendum, et eleifend nisl tristique. Pellentesque fringilla lorem id nibh auctor sagittis. Suspendisse non nisl at velit malesuada bibendum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent volutpat enim arcu, eget tempor nibh congue a. Maecenas faucibus sagittis nibh, in bibendum ex. Donec eu ornare augue, nec cursus arcu. Vivamus accumsan mauris nec nulla bibendum, et eleifend nisl tristique. Pellentesque fringilla lorem id nibh auctor sagittis. Suspendisse non nisl at velit malesuada bibendum."
image: "../../public/assets/images/dp.jpg"
subtitle: "An Awesome Web delevoper on planet"
title: "PRESENTATION"
__proto__: Object

But if I am trying to use the line 6 I got the error which is the title of my post:

TypeError: Cannot destructure property 'title' of 'pres[0]' as it is undefined.

I have found a solution for it, but I don't like it, so I would like to have some tips from you guys that helps me to get out from this error. The eventual solution would be, instead of the line 6, to write the following lines

    const title = pres[0]?.title;
    const subtitle = pres[0]?.subtitle;
    const image = pres[0]?.image;
    const description = pres[0]?.description;

In this way everything is working, but this can be fine in this situation where I have few fields and is just one line of array.

So, is it possibile to use the 6th line of the code, with some corrections, instead of using all this ammound of code?

Upvotes: 0

Views: 552

Answers (1)

Drew Reese
Drew Reese

Reputation: 202836

Basically your initial state is an empty array, so pres[0] is undefined and you can't destructure properties from it.

const initialState = {
  presentation: [],
}

Instead of using Optional Chaining syntax to access nested properties you can instead use Nullish Coalescing operator to provide a fallback value to destructure from. This provides a fallback value in the case the left hand side is null or undefined.

const { title, subtitle, image, description } = pres[0] ?? {};

Upvotes: 2

Related Questions