I’m following Jonas Schmedtmann’s full-stack crash course, and everything is fine. But in this part, I’m receiving a React runtime error (TypeError: Cannot read properties of undefined (reading 'color')
) while I’m coding everything that he codes.
Error is related to this part of the component I paste below:
<span
className="tag"
style={{
backgroundColor: CATEGORIES.find((cat) => cat.name === fact.category)
.color,
}}
onClick={() => setCurrentCategory(fact.category)}>
{fact.category}
</span>
This is the full component.
function Fact({ fact, setCurrentCategory, setFacts }) {
const [isUpdating, setIsUpdating] = useState(false);
async function handleVote(vote) {
if (vote) {
setIsUpdating(true);
const { data: updatedFact, error } = await supabase
.from("facts")
.update({ [vote]: fact[vote] + 1 })
.eq("id", fact.id)
.select();
if (!error) {
setIsUpdating(false);
setFacts((facts) =>
facts.map((f) => (f.id === fact.id ? updatedFact[0] : f))
);
}
}
}
return (
<li className="fact">
<p>
{fact.text}
<a
className="source"
href={fact.source}
target="_blank"
rel="noreferrer">
(Source)
</a>
</p>
<span
className="tag"
style={{
backgroundColor: CATEGORIES.find((cat) => cat.name === fact.category)
.color,
}}
onClick={() => setCurrentCategory(fact.category)}>
{fact.category}
</span>
<div className="vote-buttons">
<button
onClick={() => handleVote("vote_interesting")}
disabled={isUpdating}>
👍 {fact.vote_interesting}
</button>
<button
onClick={() => handleVote("vote_mindBlowing")}
disabled={isUpdating}>
🤯 {fact.vote_mindBlowing}
</button>
<button onClick={() => handleVote("vote_false")} disabled={isUpdating}>
⛔ {fact.vote_false}
</button>
</div>
</li>
);
}
So, every "fact" object, has a "category" property. Categories and their colors are also defined in an array like this:
const CATEGORIES = [
{ name: "technology", color: "#3b82f6" },
{ name: "science", color: "#16a34a" },
{ name: "finance", color: "#ef4444" },
{ name: "society", color: "#eab308" },
{ name: "entertainment", color: "#db2777" },
{ name: "health", color: "#14b8a6" },
{ name: "history", color: "#f97316" },
{ name: "news", color: "#8b5cf6" }
];
The autocompletion of VS code also recommends the ‘color’ property to use at the line which gives the error, but nothing works.
This is the link of the full file of code.
I have no idea why I’m receiving this error.
2
Answers
Array.find
potentially returnsundefined
if there is not any matching array element that passes the predicate function.You should guard against
undefined
accesses. One way to do this is to use the Optional Chaining Operator on thecolor
property.If necessary, it’s common to also use the Nullish Coaliscing Operator to provide a fallback value in case a matching element color is not found, i.e. if it is
null
orundefined
.Example:
If it is unexpected that the
fact.category
is not a value defined in yourCATEGORIES
array, then either updateCATEGORIES
to include the missing name/category color value, or double-check your fetchedfacts
data is correct.It’s better to add a question mark
?
before.color
you wrote, to avoid any runtime errors and handle everything until react fully loads.The better code could be something like below:
If you want to add a default value to the background color you can add something like
|| 'red'
after the.color
you wrote.