reactjsrecursionreact-propsarray.prototype.map

how do i get the quantity from a cart in react


i want to display products dynamically from an object called menu:

menu = [
  { id: 1
    title: soup,
    likes: 67,
    types: [
             { subid:1, subtitle: tomato, price: 1 },
             { subid:2, subtitle: carrot, price: 2 }
           ]
  },
  {
    id: 2
    title: taco,
    likes: 47
    types: [  
             { subid:3, subtitle: beef, price:4 },
             { subid:4, subtitle: pork, price:2 },
             { subid:5, subtitle: fish, price:5 }
           ]  
  }
]

and i was displaying them with a component and a map function like this

return (
   <div className="Cards-container">
     { menu.map((food) => (
       <Card
         Title={food.title}
         Likes={food.likes}
         Id={food.id}
       />
   </div>
)

and i have another component in that Card called Mob

function Card(props) {
  return (
    <div>
      <h3>{props.Title}</h3>
      <p>{props.Likes}</p>
      <Mob
        Title={props.Title}
        Id={props.Id}
      />
    </div>
  )
}

I had to condition the rendering since it returned all the types and not those belonging to the selected food

const Mob = (props) = > {
  const cart = useContext(CartContext);
  const productQuantity = cart.getProductQuantity(props.Id);
console.log(cart.items);
return menu.map((food) => 
  food.id === props.Id ? (
    food.types.map((type)=>(
      <div>
        <p>{type.subtitle}</p>
        <button onClick={()=> cart.addOneTocart(type.id)}>+</button>
        <p>{productQuantity}</p>
        <button onClick={()=> cart.removeOneFromCart(type.id)}>-</button>
      </div>
    ))
  )
}

Here is the getProductQuantity function

function getProductQuantity(id) {
        const quantity = cartProducts.find(product => product.id === id)?.quantity;
        
        if (quantity === undefined) {
            return 0;
        }

        return quantity;
    }

In summary, everything works except when showing the number of items in the cart because the food id is passing but I need the subid

I tried to apply another map function to the first component where the card is and set the subids in the props like this SubId={type.subid} but ends up showing 5 cards instead of just two cards

this is what i tried.

menu.map((food) => (
  food.types.map((type)=>(
   <Card
         Title={food.title}
         Likes={food.likes}
         Id={food.id}
         SubId={type.subid}
   />
  ))
))

any ideas?


Solution

  • A couple of things,

    for example:

    {menu.map((food) => (
          <Card
            title={food.title}
            likes={food.likes}
            id={food.id}
            key={food.id}
            types={food.types} // drill this prop down to children
          />
        ))}
    
    

    in you card comp, you want to render Mob comp and pass the types array to it

    function Card({title, likes, types}) {
      return (
        <div>
          <h3>{title}</h3>
          <p>{likes}</p>
          <Mob
            types={types}
          />
        </div>
      )
    }
    
    

    finally in your Mob comp, you want to loop over the types and then get the product quantity using its subid.

    const Mob = ({types}) => {
      const cart = useContext(CartContext);
    
      return types.map((type) => {
        const productQuantity = cart.getProductQuantity(type.subid);
        
        return (
          <div key={type.subid}>
            <p>{type.subtitle}</p>
            <button onClick={()=> cart.addOneTocart(type.subid)}>+</button>
            <p>{productQuantity}</p>
            <button onClick={()=> cart.removeOneFromCart(type.subid)}>-</button>
          </div>
        )
      });
    }
    

    this should get you going