Syyam Noor
Syyam Noor

Reputation: 504

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

Upvotes: 2

Views: 1086

Answers (2)

Logar
Logar

Reputation: 1248

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) => {
     //..
 });

Upvotes: 2

Faruk Yazici
Faruk Yazici

Reputation: 2404

In this case, you have to make a simple control before pushing, whether the item exists or not. It's up to you to design it:

For example, you could create another list that holds the unique items. In such a page, I believe it is useful to hold the unique items, you might need related information somewhere else too. And this list shouldn't require setState because it's just for the control.

this.state.uniqueItems = [];

In each push, add the item to the uniqueItems. Do not use setState here because it will cause redundant render:

this.state.uniqueItems.push(item);

In the map function, before pushing, check if it the id exists in the unique list. You could use a simple for loop, or lodash library, or Array's find method here.

Upvotes: 0

Related Questions