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.
Array.find
potentially returns undefined
if there is not any matching array element that passes the predicate function.
Return value
The first element in the array that satisfies the provided testing function. Otherwise,
undefined
is returned.
You should guard against undefined
accesses. One way to do this is to use the Optional Chaining Operator on the color
property.
CATEGORIES.find((cat) => cat.name === fact.category)?.color
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
or undefined
.
Example:
CATEGORIES.find((cat) => cat.name === fact.category)?.color ?? "#fff" // white
If it is unexpected that the fact.category
is not a value defined in your CATEGORIES
array, then either update CATEGORIES
to include the missing name/category color value, or double-check your fetched facts
data is correct.