Search code examples
javascriptreactjsreact-nativeconditional-rendering

How to map items from an object that are unique and not repeating


I am making an E-Commerce react native app and in the CART section of the app, I want every item added in a cart with the same ID (categoryID as you can see in the console) to render only once, but in my case if I add 3 items with same id in the cart, I will see 3 different listItems of their respected items. I want my map function to show 1 list item if there are multiple items with same id with quantity getting added. My code so far is just rendering every selected product as a separate item:

renderItems() {
let items = [];
this.state.cartItems.map((item, i) => {
  console.log(item)
  items.push(
    <ListItem
      key={i}
      last={this.state.cartItems.length === i + 1}
      onPress={() => this.itemClicked(item)}
    >
      <Thumbnail square style={{ width: 100, height: 100 }} source={{ uri: item.productdetail.image }} />
      <Body style={{ paddingLeft: 10 }}>
        <Text style={{ fontSize: 16 }}>

          {item.productdetail.name}

        </Text>

        <Text style={{ fontSize: 14, fontStyle: 'italic' }}>Price: {item.productdetail.price}</Text>
        <Text style={{ fontSize: 14, fontStyle: 'italic' }}>Quantity: {item.quantity > 1 ? item.quantity : 1}</Text>

      </Body>
      <Right>
        <Button style={{ marginLeft: -25 }} transparent onPress={() => this.removeItemPressed(item)}>
          <Icon size={30} style={{ fontSize: 30, color: '#95a5a6' }} name='ios-remove-circle-outline' />
        </Button>
      </Right>
    </ListItem>
  );
});
return items;}

The result of console.log is as follows enter image description here

This is how my cart looks like enter image description here

Now as you can see the cart should display only one listItem with same product have quantity=18


Solution

  • Considering you have a simple data set like this :

    const rawItemsData = [
        {id: 1, qty: 2},
        {id: 1, qty: 3},
        {id: 2, qty: 1},
        {id: 1, qty: 2},
        {id: 2, qty: 5},
        {id: 3, qty: 6}
    ];
    

    If you want to get an array with unique item ids and summed qty, you can use reduce :

    const uniqueItemsData = rawItemsData.reduce((prev, item) => {
        const existingItem = prev.find(({id}) => id === item.id);
        if(existingItem)
            existingItem.qty = existingItem.qty + item.qty;
        else
            prev.push(item);
       return prev;
     }, []); //-> [ { id: 1, qty: 7 }, { id: 2, qty: 6 }, { id: 3, qty: 6 } ];
    
    
     //Then you can use your code : 
     uniqueItemsData.map((item, id) => {
         //..
     });