Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reactjs objectlist groupby and map over

I am using map to render a list op products in my app. Like this:

<div className={`content ${isLoading ? 'is-loading' : ''}`}>
  <div className="panel">
    {!isLoading && orders.length > 0
      ? orders.map((order, index) => {
          const { productname, image, quantity, orderid, category } = order;
          return (
            <div className="product" key={orderid}>
              <div className="plaatjediv" onClick={this.toggleModal.bind(this)}>
                <img
                  className="img-responsive"
                  data-itemIndex={index}
                  src={image}
                />
              </div>
              <div className="productInfo">
                <p>{productname}</p>
                <p>Aantal: {quantity}</p>
              </div>
              <div className="bdone">
                <button
                  className="btn btn-lg btn-default btndone"
                  data-itemIndex={index}
                  onClick={this.handleDoneAction}
                >
                  Done
                </button>
              </div>
            </div>
          );
        })
      : null}
  </div>
</div>;

the state orders is loaded with this piece of code:

fetch('http://localhost:54408/api/orders/all/testing-9!8-7!6/' + todayy)
  .then(response => response.json())
  .then(parsedJSON =>
    parsedJSON.map(product => ({
      productname: `${product.ProductName}`,
      image: `${product.Image}`,
      quantity: `${product.Quantity}`,
      category: `${product.Category}`,
      orderid: `${product.OrderId}`,
    }))
  )
  .then(orders =>
    this.setState({
      orders,
      isLoading: false,
    })
  )
  .catch(error => console.log('parsing failed', error));

now I want to group the products by category and output it like this:

 - <h3>category 1</h3>
    - image - productname - quantity
    - image - productname - quantity
 - <h3>category 2</h3>
   - image - productname - quantity
   - image - productname - quantity

and so forth

I have no idea how to group my products by category and display them ordered by category with the category name as title per productgroup. I hope someone can help me further.

UPDATE

I managed to group the array to

enter image description here

but I can't get it to render with map or something else.

The category names are for now numbers, but this might chance later.

like image 703
valheru Avatar asked Oct 15 '25 08:10

valheru


2 Answers

Your first step would be to group your data using something like What is the most efficient method to groupby on a JavaScript array of objects? or lodash groupBy.

Your data will then look something like:

const data = [{
  category: 'category1',
  orders: [
    {productname: 'pn1', image: 'img1', quantity: 1, orderid: 'ord1'},
    {productname: 'pn2', image: 'img2', quantity: 2, orderid: 'ord2'}
  ]
}, {
  category: 'category2',
  orders: [
    {productname: 'pn3', image: 'img3', quantity: 1, orderid: 'ord3'},
    {productname: 'pn4', image: 'img4', quantity: 2, orderid: 'ord4'},
    {productname: 'pn5', image: 'img5', quantity: 2, orderid: 'ord4'},
  ]
}];

Then you can use two nested .map in your render method:

render() {
  return Object.keys(data).map(cat => (
    <div>
      <h3>{cat}</h3>
      {data[cat].map(ord => (
        <div>
          <div>{ord.productname}</div>
          <div>{ord.image}</div>
          <div>{ord.quantity}</div>
          <div>{ord.orderid}</div>
        </div>
      ))}
    </div>
  ))
}
like image 183
klugjo Avatar answered Oct 18 '25 01:10

klugjo


You can group your data by categoryId before rendering it

groupBy = (data, key) {
  return data.reduce(function(acc, item) {
    (acc[item[key]] = acc[item[key]] || []).push(item);
    return acc;
  }, {});
};
renderData() {
   const data = this.groupBy(this.state.orders, 'category');
   return Object.keys(data).map(objKey => <React.Fragment key={objKey}>{
       <h3>{objKey}</h3>
       {data[objKey].map(order => <ul>
           <li>{order.image}</li>
           <li>{order.Quantity}</li>
           <li>{order.ProductName}</li>
        </ul>) }
   }</React.Fragment>)
}
render() {
    <div>{this.renderData()}</div>
}
like image 26
Shubham Khatri Avatar answered Oct 18 '25 02:10

Shubham Khatri



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!