marwari
marwari

Reputation: 191

mat-selection-list with nested for loop in angular

The dataset I'm getting in my API is as following:

product name category rating
iPhone Smart Phone 3
iPhone Apple 3
Motorola Smart Phone 4

How I want to show this is like Product Name as header then Categories of the product belongs to and then review:

Product name then categories

There should be only one entry for each product and all the categories for that should be comma separated below that.

I'm using mat-selection-list and my code look like this:

<div class="products-box">
        <mat-selection-list #products color="primary">
          <mat-list-option
            class="p-1 m-1"
            checkboxPosition="before"
            *ngFor="let product of products"
          >
            <div class="row">
              <div class="col">
                {{ product.name }}
              </div>
              <div class="col-auto">
               {{ product.rating }}
              </div>
            </div>
            <div class="row">
              <div class="col-md-12 text-muted">{{ product.category }}</div>
            </div>
          </mat-list-option>
        </mat-selection-list>
      </div>

How should I write nested for loop so I get comma separated categories for each product?

Upvotes: 0

Views: 937

Answers (1)

tnc1997
tnc1997

Reputation: 1962

I have created a minimum working example here which uses Lodash's groupBy function to group the list of products by the productName. This method has the benefit of only requiring the grouping logic to be undertaken once when the page loads for the first time.

Models

export interface ProductCategoryRanking {
  productName: string;
  category: string;
  rating: number;
}

Services

import { Injectable } from "@angular/core";
import { ProductCategoryRanking } from "./product-category-ranking";

@Injectable({
  providedIn: "root"
})
export class ProductCategoryRankingService {
  get(): ProductCategoryRanking[] {
    return [
      {
        productName: "iPhone",
        category: "Smart Phone",
        rating: 3
      },
      {
        productName: "iPhone",
        category: "Apple",
        rating: 3
      },
      {
        productName: "Motorola",
        category: "Smart Phone",
        rating: 4
      }
    ];
  }
}

Components

import { Component, OnInit } from "@angular/core";
import _ from "lodash";
import { ProductCategoryRanking } from "./product-category-ranking";
import { ProductCategoryRankingService } from "./product-category-ranking.service";

/**
 * @title List with selection
 */
@Component({
  selector: "list-selection-example",
  styleUrls: ["list-selection-example.css"],
  templateUrl: "list-selection-example.html"
})
export class ListSelectionExample implements OnInit {
  productCategoryRankings: _.Dictionary<ProductCategoryRanking[]>;

  constructor(
    private productCategoryRankingService: ProductCategoryRankingService
  ) {}

  ngOnInit(): void {
    this.productCategoryRankings = _.groupBy(
      this.productCategoryRankingService.get(),
      "productName"
    );
  }

  getCategory(productCategoryRankings: ProductCategoryRanking[]): string {
    return productCategoryRankings.map(value => value.category).join(", ");
  }

  getRating(productCategoryRankings: ProductCategoryRanking[]): number {
    return productCategoryRankings.map(value => value.rating)[0];
  }
}

/**  Copyright 2020 Google LLC. All Rights Reserved.
    Use of this source code is governed by an MIT-style license that
    can be found in the LICENSE file at http://angular.io/license */
<mat-selection-list #values color="primary">
  <mat-list-option
    *ngFor="let kvp of productCategoryRankings | keyvalue"
    class="p-1 m-1"
    checkboxPosition="before"
  >
    <div class="row">
      <div class="col">
        {{ kvp.key }}
      </div>
      <div class="col-auto">
        {{ getRating(kvp.value) }}
      </div>
    </div>
    <div class="row">
      <div class="col-md-12 text-muted">
        {{ getCategory(kvp.value) }}
      </div>
    </div>
  </mat-list-option>
</mat-selection-list>

<p>
  Options selected: {{ values.selectedOptions.selected.length }}
</p>

<!-- Copyright 2020 Google LLC. All Rights Reserved.
    Use of this source code is governed by an MIT-style license that
    can be found in the LICENSE file at http://angular.io/license -->

Upvotes: 1

Related Questions