Implementing ngFor to group values within div containers according to specific keys

In my Angular application, I am working with an array named calendarDates that holds various date-related information.

calendarDates = [
  {"date": "2018-10-23", "day": 5, "month":10, "year":2018, "price":"500", "date_is_valid": true},
  {"date": "2018-10-24", "day": 6, "month":10, "year":2018, "price":"550", "date_is_valid": false},
  ...
  {"date": "2018-11-01", "day": 1, "month":11, "year":2018, "price":"600", "date_is_valid": true},
  ...
  {"date": "2019-02-01", "day": 2, "month":12, "year":2019, "price":"700", "date_is_valid": false}
]

I am aiming to render this data in HTML where each month has its own wrapper div:

<div *ngFor='let calendarDate of calendarDates'>
  <div class='month'>
    <div class='october'>
      <p>October</p>
      <div class='date'>{{calendarDate.date}} (2018-10-23)</div>
      <div class='date'>{{calendarDate.date}} (2018-10-24)</div>
      ...
    </div>
    <div class='november'>
      <p>November</p>
      <div class='date'>{{calendarDate.date}} (2018-11-01)</div>
      ...
    </div>
    <div class='february'>
      <p>February</p>
      <div class='date'>{{calendarDate.date}} (2019-02-01)</div>
      ...
    </div>
  </div>
</div>

I am struggling with filtering the data and organizing it by month in the HTML itself. How can I achieve this using ngIf directives while ensuring that changes in values like price or date validity are reflected dynamically?

Answer №1

To categorize items, you can create a custom pipe called GroupByPipe.

Group By Pipe

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({name: 'groupBy'})
export class GroupByPipe implements PipeTransform {
    transform(collection: Array, property: string): Array {
        if(!collection) {
            return null;
        }

        const groupedCollection = collection.reduce((previous, current)=> {
            if(!previous[current[property]]) {
                previous[current[property]] = [current];
            } else {
                previous[current[property]].push(current);
            }

            return previous;
        }, {});

        return Object.keys(groupedCollection).map(key => ({ key, value: groupedCollection[key] }));
    }
}

For more information on how to use this pipe, you can visit

HTML Example

<div *ngFor='let calendarDatesByMonth of calendarDates | groupBy:'month''>
  <div class='month'>
    <div class='october'>
      <p>{{getMonthName(calendarDatesByMonth.key)}}</p> <!-- calendarDatesByMonth.key is the month number -->
      <div *ngFor='let calendarDate of calendarDatesByMonth.value' class='date'>{{calendarDate.date}} (2018-10-23)</div>
    </div>
  </div>
</div>

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

RxJS: Understanding the issue of 'this' being undefined when used within the subscribe method

As I work on setting up a simple error notifications component and debug in Visual Studio, an issue arises within the subscribe function where 'this' is undefined. public notifications: NotificationMessage[]; constructor(notificationService: N ...

How to dynamically set options in Angular 4 by value

I have 2 option sets (picklists) and I want to populate one based on the selection from the other. For example, consider the arrays in the ts file: carsArray: { id: number, name: string }[] = [ { "id": 1, "name": "Car1" }, { "id": 2, "name": "C ...

Encountering an issue with TypeScript after applying a wrapper to a Material-UI button - specifically, the error message states that the type '{ children: string; color: "light-green"; }' is lacking certain properties

I'm currently working on creating wrapped components using MUI (@material-tailwind/react) within the environment of Next.js 14. However, I've run into a typescript error specifically in the MaterialButton component. Type '{ children: string; ...

What is the correct way to assign a property to a function's scope?

Lately, I've been delving into Typescript Decorators to address a specific issue in my application. Using a JS bridge to communicate TS code between Android and iOS, we currently define functions as follows: index.js import foo from './bar' ...

Create Open Graph meta tags dynamically using the MEAN stack, including Angular 2+

I'm currently working on creating unique OG tags for specific item-detail pages. I am using the meta module for Angular from https://github.com/nglibs/meta to generate these meta tags, which work perfectly fine in browsers. However, when it comes to F ...

The initial function that gets executed in the lodash chain is tap()

When using lodash chain to perform actions synchronously, I encountered an issue where .tap() is executed before the desired stage. I have been unable to find a solution using promises. I expected lodash chain to ensure actions are carried out in a synch ...

Using Angular 6 pipes can simplify observable operations by eliminating the need for explicit typing

Recently, I upgraded my application from Angular5 to 6. Upon completing the update, I proceeded to migrate to rxjs6, which resulted in a change in my code where I was utilizing the takeWhile method. As a result, in order to subscribe to a service, my code ...

Adding an external component to an Angular 2 project

I've been facing challenges while trying to import an external component from a URL into a new Angular2 application. The issue I keep encountering is with the typescript failing to compile and run the application smoothly. Here is the specific import ...

Access Select without needing to click on the child component

I am curious to learn how to open a Select from blueprint without relying on the click method of the child component used for rendering the select. <UserSelect items={allUsers} popoverProps={{ minimal: false }} noResults={<MenuItem disabled={ ...

Button to expand or collapse all sections in Ant Design Collapse component

Is there a way to create a button that can expand or collapse all tabs in an ant.design Collapse component? I attempted to modify defaultActiveKey but it seems like this can only be done during page rendering. If possible, could someone share a code snip ...

Google Chrome - Automatically scroll to the bottom of the list when new elements are added in *ngFor loop

I have a basic webpage showcasing a list of videos. Towards the bottom of the page, there is a button labeled "Load more". When a user clicks on this button, an HTTP request is triggered to add more data to the existing array of videos. Here is a simplifi ...

Guide to utilizing vue-twemoji-picker in TypeScript programming?

Has anyone encountered this issue when trying to use vue-twemoji-picker in a Vue + TypeScript project? I keep receiving the following error message. How can I fix this? 7:31 Could not find a declaration file for module '@kevinfaguiar/vue-twemoji-picke ...

The 'string[]' type cannot be assigned to the 'string | ParsedUrlQueryInput | null | undefined' type in Next.js and Typescript

I'm facing an issue while attempting to transfer an array of strings from one page to another in Next.js using <Link href={{ pathname: "/model", query: data }}>. The problem arises when the query parameter is red underlined: Type &apos ...

A guide on incorporating Union Types in TypeScript

Currently utilizing typescript in a particular project where union types are necessary. However, encountering perplexing error messages that I am unsure how to resolve. Take into consideration the type definition below: type body = { [_: string]: | & ...

Angular throwing TypeError: Trying to access 'name' property of an undefined variable

I'm facing an issue where I can't display the user's name on the dashboard toolbar after they log in. The browser console is showing that UserDetails is undefined when trying to call the UserDetails interface, despite importing it from anoth ...

What could be the cause of this malfunction in the Angular Service?

After creating an Angular app with a controller, I noticed that while I can successfully interact with the controller using Postman (as shown in the screenshot below), I faced issues with displaying data at the frontend. I implemented a new component alon ...

What is the best way to iterate through two object keys in TypeScript?

I recently created a Vector class but I am encountering some issues with the syntax. Here is the code snippet: export class Vector { x: number; y: number; constructor(x = 0, y = 0) { this.x = x; this.y = y; } add(v: Vector) { var x ...

The server.js file is malfunctioning and unable to run

Here are the versions I am using in my application: "node": "7.2.1", "npm": "4.4.4" "@angular/cli": "1.4.9", "@angular/core": "4.4.6" After deploying my application on Heroku, it built successfully. However, when I try to run it, I encounter an "Applica ...

Incorporating an external TypeScript script into JavaScript

If I have a TypeScript file named test.ts containing the code below: private method(){ //some operations } How can I access the "method" function within a JavaScript file? ...

Mastering the Art of Flex Layout Grids

Here is a preview of how my grid is currently formatted: https://i.stack.imgur.com/SBChV.png The current code looks like this: <div fxLayout="row wrap"> <img class="component-logo" fxFlex="1 1 c ...