Displaying grouped arrays efficiently in Angular

I have received data from an API in the form of an array with objects structured like so:

[
  {"desc":"a", "menu": 1},{"desc":"b", "menu": 2},{"desc":"c", "menu": 1}, 
  {"desc":"d", "menu": 3},{"desc":"e", "menu": 3},{"desc":"f", "menu": 2}, 
  {"desc":"g", "menu": 1},{"desc":"g", "menu": 1},{"desc":"g", "menu": 4}, 
  {"desc":"g", "menu": 4},{"desc":"g", "menu": 4}
]

I want to display these objects using *ngFor, grouped by their "menu" property, and with a corresponding label for each group as follows:

Menu 1

{all objects with menu 1}

Menu 2

{all objects with menu 2}

Menu 3

{all objects with menu 3}

To achieve this, I plan to use *ngFor and set up logic to create labels for each menu group. Here is a rough outline of how I would approach it:

*ngFor="let object of objects; let currentMenu = 0"
     if currentMenu !== object.menu
           currentMenu === object.menu
       CREATE LABEL

If you have any suggestions on how to implement this effectively in actual code, please share them!

Answer №1

To improve the efficiency, I suggest grouping the data before utilizing the *ngFor directive. Here is a possible solution:


function groupBy(array, key) {
    return array.reduce((acc, current) => {
        (acc[current[key]] = acc[current[key]] || []).push(current);
        return acc; 
      }, {});
}

function toArray(obj) {
    return Object.keys(obj).map(key => obj[key]);
}

const data = [
  {"desc":"a", "menu": 1},{"desc":"b", "menu": 2},{"desc":"c", "menu": 1}, 
  {"desc":"d", "menu": 3},{"desc":"e", "menu": 3},{"desc":"f", "menu": 2}, 
  {"desc":"g", "menu": 1},{"desc":"g", "menu": 1},{"desc":"g", "menu": 4}, 
  {"desc":"g", "menu": 4},{"desc":"g", "menu": 4}
]

const groupedData = groupBy(data, "menu");

Then, in your template, you can utilize the grouped data like this:


<group *ngFor="let group of groupedData">
  <menu *ngFor="let item of group">
    <label>{{item.desc}}</label>
  </menu>
</group>

Answer №2

You can implement a solution like this:

ngOnInit(){
    var groups = new Set(this.array.map(item => item.menu))
    this.result = [];
    groups.forEach(g => 
      this.result.push({
        menu: g, 
        values: this.array.filter(i => i.menu === g)
      }
    ))
  }

This code snippet shows how to render the data in HTML:

<p>
    Start editing and see the magic happen :)
</p>
<div *ngFor="let item of result" border="1">
    <table>
        <tr>
            <th>Desc</th>
            <th>Menu</th>
        </tr>
        <ng-container>
            <tr>
                <td colspan="2">{{item.menu}}</td>
            </tr>
            <tr *ngFor="let value of item.values">
                <td>{{value.desc}}</td>
            </tr>
        </ng-container>
    </table>
    <div>

Feel free to check out the stackblitz I created. https://stackblitz.com/edit/angular-4ekz4n

Happy coding! :)

Answer №3

Learn how to write import statements within an Angular component

import { of } from 'rxjs';
import { groupBy, mergeMap } from 'rxjs/operators';

Next, add the following code snippet inside the ngOnInit() method:

ngOnInit():void{
on(
    {id: 1, name: 'JavaScript'},
    {id: 2, name: 'Parcel'},
    {id: 2, name: 'webpack'},
    {id: 1, name: 'TypeScript'},
    {id: 3, name: 'TSLint'}
).pipe(groupBy(a=>a.id)),
 mergeMap((group$) => group$.pipe(reduce((acc, cur) => [...acc, cur], []))),
)
.subscribe(p => console.log(p));

//The expected output will be as follows:

[ { id: 1, name: 'JavaScript'},
{ id: 1, name: 'TypeScript'} ]
[ { id: 2, name: 'Parcel'},
  { id: 2, name: 'webpack'} ]
[ { id: 3, name: 'TSLint'} ]

For further details, visit rxJS operators for groupBy

Answer №4

The first step is to restructure the current array to match the format below:

[
  {
    category: 1,
    items: ["a", "b"]
  },
  {
    category: 2,
    items: ["a1", "b1", "c1", "d1"]
  }
]

You can achieve this by iterating through the current array in the component's TypeScript file and organizing it as demonstrated in the example above.

Once you have updated the array, you can use it with *ngFor in the HTML to display the data.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to navigate back to the previous page while retaining parameters?

Is there a way to return to the previous page with specific parameters in mind? Any suggestions on how to achieve this? import {Location} from '@angular/common'; returnToPreviousPage(){ this._location.back(); } What I am looking ...

The server's response is unpredictable, causing Json.Parse to fail intermittently

I have encountered a strange issue that is really frustrating. It all started when I noticed that my Json.Parse function failed intermittently. Here is the code snippet in question: const Info = JSON.parse(response); this.onInfoUpdate(Info.InfoConfig[0]); ...

I am looking to access a public method from a different component in Angular 2

Trying to access the headerExpand property from app.component is causing an error message in the console: metadata_resolver.js:559 Uncaught Error: Invalid providers for "Page1" - only instances of Provider and Type are allowed, got: [?undefined?] page1 ...

Implementing Dynamic Component Rendering in React Native with Typescript

For the past 3 hours, I've been grappling with this particular issue: const steps = [ { Component: ChooseGameMode, props: { initialValue: gameMode, onComplete: handleChooseGameModeComplete } }, { Com ...

Find the combined key names in an object where the values can be accessed by index

I am currently working on creating a function called indexByProp, which will only allow the selection of props to index by if they are strings, numbers, or symbols. This particular issue is related to https://github.com/microsoft/TypeScript/issues/33521. ...

Ways to showcase product information (Using Angular and Firebase)

Information product.model.ts id?: string; name: string; price: number; sale_price: number; description: string; tech_sheet: string; imageUrls: string[]; category: string; createdAt: Date; } Initialize file product.service.ts The latest f ...

Discover the syntax for reading route parameters in Angular

Currently, I am integrating the Paypal API into my project. After confirming a purchase, Paypal redirects to a specified URL. I set the desired URL as "localhost:4200/shop/order". However, when Paypal returns the URL, it appends the token and payerid at th ...

Managing input and output using a collaborative service

I've been working on refactoring some code that contains a significant amount of duplicate methods between two components. Component A is a child of component B, and they can be separate instances as intended. The issue I'm facing revolves around ...

Exploring the power of Vue CLI service in conjunction with TypeScript

I've recently set up a Vue project using the Vue CLI, but now I am looking to incorporate TypeScript into it. While exploring options, I came across this helpful guide. However, it suggests adding a Webpack configuration and replacing vue-cli-service ...

Testing a function that utilizes Nitro's useStorage functionality involves creating mock data to simulate the storage behavior

I have developed a custom function for caching management, specifically for storing responses from API calls. export const cache = async (key: string, callback: Function) => { const cacheKey = `cache:${key}`; const data = await useStorage().get ...

Incorporating TypeScript's internal references

I am currently working on defining my own model interface that extends the Sequelize model instance. However, I am encountering difficulties in referencing the Sequelize interface within my code. Specifically, I receive an error stating "Cannot find name ...

Webpack 5: Updating the file path for TypeScript declaration files

My project structure includes a crucial src/ts folder: - dist/ - js/ - css/ - index.html - about.html - src/ - assets/ - fonts/ - images/ - sass/ - ts/ - services/ - service1.ts - ...

Exploring the way to reach a specific page in Ionic3

Is there a way to navigate from a child page back to its parent page without the URL getting messed up? It seems like when I try to do this, the child remains unchanged while only the parent page updates. If this is correct, how can I remove the child fr ...

Angular: The type AbstractControl<any> cannot be assigned to type FormControl

I am working with a child component that includes an input tag <input [formControl]="control"> component.ts file @Input() control: FormControl; In the parent component, I am using it as follows: <app-input [control]="f['email ...

Displaying a component inside a different component

I'm attempting to display components inside another component, but even when I try to include div elements within the component, they don't show up. const DisplayComponent = () => { return ( <div> <DisplayContent ...

Improving event observation efficiency with Observable.fromEvent on the browser window

Within my file manager UI, each individual file item is currently set to monitor the window's wheel event. As soon as a file item comes into view on the page, its corresponding image loading process will be initiated by the file item component. While ...

Assign object properties to a constant variable while validating the values

When receiving the features object, I am assigning its values to constants based on their properties. const { featureCode, featureSubType, contentId, price, family: { relationCountsConfig: { motherCount, fatherCount, childrenCount }, max ...

What is the best way to reset a setInterval ID in Angular?

In my Angular project, I am developing a simple timer functionality that consists of two buttons – one button to start the timer and another to stop it. The timer uses setInterval with a delay of 1000ms. However, when the stop button is pressed, the time ...

Using Typescript for-loop to extract information from a JSON array

I'm currently developing a project in Angular 8 that involves utilizing an API with a JSON Array. Here is a snippet of the data: "success":true, "data":{ "summary":{ "total":606, "confirmedCasesIndian":563, "con ...

Errors in the Latest Release of Angular2 and Visual Studio 2015

After taking a stroll through the Angular 2 Tour of Heroes sample application with the latest Angular 2 version, I decided to host it within a Visual Studio 2015 Empty Web application. Following the Angular sample closely means that I'm not incorporat ...