Reputation: 191
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:
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
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.
export interface ProductCategoryRanking {
productName: string;
category: string;
rating: number;
}
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
}
];
}
}
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