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

Time:11-13

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.

CodePudding user response:

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>
  );
};

CodePudding user response:

Make sure item id is number not string

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

CodePudding user response:

let {itemId} = useParams();

Type of itemId in here is string. You need to parse it to Number before checking against your item list because I see that you have id as a number in your item list.

CodePudding user response:

you should convert itemId type to number before use it in comparisons:

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

or

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

  • Related