Working my way through my first fullstack MERN app that allows a user to add multiple places to an array. Trying to map over the array to display the number of places for the user. Code works fine until I use .length
, then it crashes.
import React from 'react';
import UserItem from './UserItem';
import Card from '../../shared/ponents/UIElements/Card/Card';
import './UsersList.css';
const UsersList = props => {
if (props.items.length === 0) {
return (
<div className="center">
<Card>
<h2>No users found.</h2>
</Card>
</div>
);
}
return (
<ul className="users-list">
{props.items.map(user => (
<UserItem
key={user.id}
id={user.id}
image={user.image}
name={user.name}
// placeCount={user.places.length}
placeCount={user.places}
/>
))}
</ul>
);
};
export default UsersList;
The full error stack:
Uncaught TypeError: Cannot read properties of undefined (reading 'length')
The above error occurred in the <UsersList> ponent:
Consider adding an error boundary to your tree to customize error handling behavior.
Visit to learn more about error boundaries.
I did a keyword search of .length
throughout the backend and frontend files to double check the code and make sure I didn't have any typos anywhere--but for the life of me I can't figure out why adding .length
isn't working.
I've gone through a few different posts on here but cannot find a working solution.
Any insight would be greatly appreciated. For now I just mented out .length
so I can keep working. Thank you!
Working my way through my first fullstack MERN app that allows a user to add multiple places to an array. Trying to map over the array to display the number of places for the user. Code works fine until I use .length
, then it crashes.
import React from 'react';
import UserItem from './UserItem';
import Card from '../../shared/ponents/UIElements/Card/Card';
import './UsersList.css';
const UsersList = props => {
if (props.items.length === 0) {
return (
<div className="center">
<Card>
<h2>No users found.</h2>
</Card>
</div>
);
}
return (
<ul className="users-list">
{props.items.map(user => (
<UserItem
key={user.id}
id={user.id}
image={user.image}
name={user.name}
// placeCount={user.places.length}
placeCount={user.places}
/>
))}
</ul>
);
};
export default UsersList;
The full error stack:
Uncaught TypeError: Cannot read properties of undefined (reading 'length')
The above error occurred in the <UsersList> ponent:
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs/link/error-boundaries to learn more about error boundaries.
I did a keyword search of .length
throughout the backend and frontend files to double check the code and make sure I didn't have any typos anywhere--but for the life of me I can't figure out why adding .length
isn't working.
I've gone through a few different posts on here but cannot find a working solution.
Any insight would be greatly appreciated. For now I just mented out .length
so I can keep working. Thank you!
- 1 How are you using this ponent – Daniel A. White Commented Jan 3, 2023 at 2:48
-
2
It seems like
items
is undefined, having you tried logging it? You have to pass items as props to theUsersList
.<UsersList items={someArrayOfItems} />
– JEEngineer Commented Jan 3, 2023 at 2:59 - Thanks for responding so quickly- just tried this and I'm still getting the same error for some reason . But Sameer's reply worked for me. Thank you again! – SJo Commented Jan 3, 2023 at 4:04
4 Answers
Reset to default 3Changing this if
condition from this:
if (props.items.length === 0) {
To
if (!props.items?.length) {
Should work.
Similarly if using for places,you can check using ternary operator if length exists in array of places.
How? Because items could possibly be null
or undefined
from apis, so the length
property on array might be missing.
Moreover, using !
Not operator would make this condition true if length of items is 0 or is null or undefined or any falsy value
The other answers are focusing on prop.items
list but in your question you mention that you get the exception when trying to access the length of the places
inside user
s.
You are getting the error message because some users may not have any places listed inside them, hence, no places list -> no length property.
To fix this, you need to check if the places list exists and then access its length:
placeCount={ user.places ? user.places.length : 0 }
Here, we use a ternary operator to check if user.places
exists, then we use the length, else use zero.
Edit: As pointed out by Phil in the ments below, you can also use coalescing operator, which is much cleaner, like this:
placeCount={ user.places?.length ?? 0 }
The syntax simply translates as if user.places has a value for length, then use that value, else use zero as a default value.
You can define a default value for items
to fix it.
const UsersList = ({ items = [] }) => {
if (items.length === 0) {
return (
...
);
}
return (
<ul className="users-list">
{items.map((user) => (
...
))}
</ul>
);
};
Here you can use object destructuring. if you are not sure whether the data will e or not. JSX will always render first and after that props, so in some cases it may render empty JSX.
you can make the changes in your ponent like this
const UsersList = props => {
const { items = [] } = props
// checking whether its an array or not and have some items in it
if (!Array.isArray(items) || items.length === 0) {
return (
<div className="center">
<Card>
<h2>No users found.</h2>
</Card>
</div>
);
}
return (
<ul className="users-list">
{items.map(user => {
const { id = "", image = "", name = "", places = "" } = user
return <UserItem
key={id}
id={id}
image={image}
name={name}
// placeCount={user.places.length}
placeCount={places}
/>
})}
</ul>
);
};