How to utilize *ngFor alongside the async pipe for conditional rendering in Angular 8 HTML

.html

<ng-container *ngFor="let contact of listContact | async; let index = index;">
      <h6 class="title" *ngIf="contact && contact['type']">
        {{contact['type']}}
        </h6>
   <div> {{contact['id']}}</div>
 </ng-container>

listContact holds an observable with the following data:

[
  {
    "id": "u-8cf4161b-240f-5d7a-b5df-0522739c62d9",
    "type": "Peoples"
  },
  {
    "id": "u-0580ff64-c959-5690-bc54-16c43b28065d",
    "type": "Peoples"
  },
  {
    "id": "u-44e5a40a-a367-55e0-baf1-1eacccafe5f2",
    "type": "Teams"
  }
]

The desired HTML output should be:

Peoples

u-8cf4161b-240f-5d7a-b5df-0522739c62d9
u-0580ff64-c959-5690-bc54-16c43b28065d

Teams
u-44e5a40a-a367-55e0-baf1-1eacccafe5f2

To prevent repeating the same {{contact['type']}} in the view if it's the same as the previous one during the loop, a check needs to be added. The title which depends on {{contact['type']}} should also not repeat until the current one is different from the previous one.

How can this issue be handled in HTML?

Answer №1

To effectively manage your items, consider categorizing them under groups such as Peoples, Teams, and so on.

If you prefer checking conditions in the template, you can save the output of listContact | async into a variable and then utilize index:

<ng-container *ngFor="let contact of listContact | async as contacts; let index = index;">
  <h6 class="title" *ngIf="contact.type && (!contacts[index - 1] || contacts[index - 1].type !== contacts[index].type)">
     {{contact.type}}
  </h6>
  <div> {{contact.id}}</div>
</ng-container>

Ng-run Example

Answer №2

If you need to group items in Angular, you can create a custom groupBy pipe.

@Pipe({ name: "groupBy" })
export class GroupByPipe implements PipeTransform {
  transform(value: Array<any>, field: string): Array<any> {
    const groupedObj = value.reduce((prev, cur) => {
      if (!prev[cur[field]]) {
        prev[cur[field]] = [cur];
      } else {
        prev[cur[field]].push(cur);
      }
      return prev;
    }, {});
    return Object.keys(groupedObj).map(key => ({
      key,
      value: groupedObj[key]
    }));
  }
}

To use this pipe in HTML, you can do the following:

<ng-container *ngFor="let contact of listContact | groupBy:'type'; let index = index;">
      <h6 class="title">
        {{contact.key}}
        </h6>
   <div *ngFor="let value of contact.value">{{value.id}}</div>
 </ng-container>

Check out a demo on Stackblitz here: https://stackblitz.com/edit/angular-groupby-pipe.

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

Observe how Observable breaks down strings into individual letters (like in Karma and Angular)

Attempting to simulate an HTTP service in Angular tests (Karma), I included the following in the providers array: { provide: service, useValue: { getData: () => new Observable((subscriber) => { subscriber.next('i ...

Altering or including new space variables within a custom Chakra-ui theme

Looking to customize spacing variables in a Chakra UI theme? I have successfully implemented various extensions, but changes to spacing are not being applied. const config: ThemeConfig = { initialColorMode: 'light', useSystemColorMode: false ...

Utilize the useState() hook to add an object and display its data in a React Native

Here is a function I am working with: const [dataLoc, setDataLoc] = useState({date: "No data received yet from sensor", coords: {}}); This is where I set the location: Geolocation.getCurrentPosition( location => { const date = d ...

Unlocking the Power of Asynchronous Data in Angular's Dynamic Form Patterns

Utilizing the dynamic form pattern in Angular has been incredibly helpful for our team. By defining our controls in ngOnInit, the form is dynamically constructed based on our needs. However, we've encountered a challenge with forms that require initia ...

Troubleshooting: @HostListener for window scroll event not functioning as expected

Having trouble creating a sticky header that stays fixed when scrolling down in an Angular 4 application. The scroll event is not being detected. The header is located in the layout component, while the content I want to be scrollable is placed in the rou ...

How to conditionally import various modules in Next.js based on the environment

Having two modules 'web,ts' and 'node.ts' that share similar interfaces can be challenging. The former is designed to operate on the client side and edge environment, while the latter depends on node:crypto. To simplify this setup, I a ...

Tips on how to effectively simulate a custom asynchronous React hook that incorporates the useRef() function in jest and react-testing-library for retrieving result.current in a Typescript

I am looking for guidance on testing a custom hook that includes a reference and how to effectively mock the useRef() function. Can anyone provide insight on this? const useCustomHook = ( ref: () => React.RefObject<Iref> ): { initializedRef: ...

Experimenting with Jest testing for a Component or Service that includes the use of "declare var" functionality

During the testing of my component or service, an error has occurred: ReferenceError: flagPath is not defined The variable flagPath is sourced from a configuration file named config.js within the assets folder. Is there a method to incorporate it into ...

Can we potentially extract shared components of a template?

As an example, I have numerous components designed for paged collections. Here is a template showcasing this: <div *ngIf="!isFormVisible"> <button class="btn" [ngClass]="{'btn-info': filtered, 'btn-default': !filtered}" (c ...

In TypeScript, an interface property necessitates another property to be valid

In the scenario where foo is false, how can I designate keys: a, b, c, bar as having an undefined/null/optional type? Put simply, I require these properties to be classified as mandatory only when foo is true. interface ObjectType { foo: boolean; a: nu ...

Visual Studio Code is unable to identify the TypeScript module located within the `node_modules` directory

After cloning the tslint repository, running npm install and grunt as instructed in the README, I opened the folder in Visual Studio Code (0.9.1). Upon inspecting a .ts file such as src/rules/typedefRule.ts, TypeScript errors appeared regarding the require ...

Tips for achieving server-side pagination with client-side sorting

Currently utilizing Angular Material's data grid, successfully loading data from the server side with sorting and pagination functionality. However, I am attempting to sort only the items visible on the table instead of sorting from the server side. ...

Angular attribute directive accesses a sibling attribute reference

Attempting to create an attribute directive named pagingContext that will work alongside the angular material sort directive matSort. The concept is to have an element structured like: <table matSort [pagingContext]="pagingContext"> With a directi ...

Unleashing the power of RXJS: Leveraging IntervalObservable coupled with the

I recently incorporated HTTP pooling into my Angular application using IntervalObservable and startWith for immediate activation. I'm curious to know if IntervalObservable waits for the initial/previous call to finish streaming data. Also, is there a ...

Is anyone able to assist with resolving the problem of `tsc` constantly monitoring `node_modules`?

Using the Expo platform has been a great experience for me. Here is a snippet from my tsconfig.json: { "compilerOptions": { "paths": { "@/*": [ "./src/*" ], ...

The VSCode Extension fails to launch after being packaged

I'm currently working on a straightforward VSCode extension that scans the active open file for any comments containing "//TODO: " and then presents a list of all TODO comments in a webview sidebar tab. While I have a functional prototype that runs s ...

Tips on setting up an npm package for automatic updates

I recently created a package called https://www.npmjs.com/package/nestjs-notifications After running npm install nestjs-notifications --save, I noticed that it installed successfully but saved the version as: "nestjs-notifications": "0.0.10 ...

Ways to eliminate angular-fontawesome from a project?

I initially added Angular fontawesome to my project using the command provided in this link: https://www.npmjs.com/package/@fortawesome/angular-fontawesome ng add @fortawesome/angular-fontawesome@6 However, I have now decided that I want to switch to Font ...

Issue in TypeScript: The module "*.svg" does not have a component that is exported named "ReactComponent"

I'm attempting to bring in an .svg file as a React component using TypeScript. As per the React documentation, the process should look like this: import { ReactComponent as Icon } from './Icon.svg'; Referring to the TypeScript documentati ...

Tips for broadcasting a router event

Currently, I am working with 2 modules - one being the sidenav module where I can select menus and the other is the content module which contains a router-outlet. I am looking for the best way to display components in the content module based on menu selec ...