Search code examples
reactjsfindundefined

Array.find() is returning undefined and I can't figure out why


In my React project, I have a page that is reading a param called "itemId" and fetching from a list of items the one item that has id === itemId. My code so far is the following. (Ellipsis "..." means code omitted for brevity.)

App.js

...
const App = () => {
  const tempItems = [
    {
      id: 1
      ...
    },
    ...
  ];

  const Routes = (
    <Routes>
      ...
      <Route path="/item/:itemId" element=<Item items={tempItems}/> exact/>
      ...
    <Routes/>
  );
};
...

Item.js

const Item = ({items}) => {
  let {itemId} = useParams();
  console.log("Item id: " + itemId);
  console.log(items);
  const item = items.find((i) => i.id === itemId);
  console.log(item);
  if (item === undefined) {
    console.log("redirected because item with id " + itemId + " doesn't exist");
    return <Navigate to="/"/>
  }
  console.log("rendering item page");
  return (    
    <div>
      <h1>Rendering item page</h1>
    </div>
  );
};

When I enter "localhost:3000/item/1", the following console logs are printed. (Please don't ask me why all the item names are corn themed, lol.)

Item id: 1

Array(8) [ {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…} ]
0: Object { id: 1, itemName: "Shepherd's Pie", itemType: "Cuisine", … }
1: Object { id: 2, itemName: "Cornmeal-Fried Fish", itemType: "Cuisine", … }
2: Object { id: 3, itemName: "Cornbread", itemType: "Side", … }
3: Object { id: 4, itemName: "Grilled corn", itemType: "Side", … }
4: Object { id: 5, itemName: "Corn Milk", itemType: "Drink", … }
5: Object { id: 6, itemName: "Corn Beer", itemType: "Drink", … }
6: Object { id: 7, itemName: "Corn Pudding", itemType: "Dessert", … }
7: Object { id: 8, itemName: "Sweet Corn Cake", itemType: "Dessert", … }
length: 8
<prototype>: Array []

undefined

redirected because item with id 1 doesn't exist

The itemId param in the URL is being parsed correctly because when I enter "localhost:3000/item/1" the console logs "Item id: 1". The items prop that I'm passing into Item.js is correct because it's printing out the complete array. But for some reason, the find function is returning undefined even though I know for a fact that the array contains an element where item.id === itemId (in this case 1). Is there some secret magic I'm missing? So far in learning React, it really seems like there's some confusing workarounds for confusing problems, so I wouldn't be surprised if there's some crazy solution that I'm missing that you can't just figure out with intuition.


Solution

  • Try use +itemId to convert itemId string to a number in items.find():

    const item = items.find((i) => i.id === +itemId)

    Read more about + operator

    Example:

    // Here the itemId type is string so need convert it later
    const {itemId} = useParams();
    
    // Handle case if there is no itemId param
    if (!itemId) return <Navigate to="/"/>
    
    console.log("Item id: " + itemId);
    console.log(items);
    
    // +itemId will convert itemId from string to number
    const item = items.find((i) => i.id === +itemId);
    

    Full Item.js with these changes:

    const Item = ({items}) => {
      const {itemId} = useParams();
    
      if (!itemId) return <Navigate to="/"/>
    
      console.log("Item id: " + itemId);
      console.log(items);
      const item = items.find((i) => i.id === +itemId);
      console.log(item);
      if (item === undefined) {
        console.log("redirected because item with id " + itemId + " doesn't exist");
        return <Navigate to="/"/>
      }
      console.log("rendering item page");
      return (    
        <div>
          <h1>Rendering item page</h1>
        </div>
      );
    };