Sorting and dividing an Array using Angular

Forgive me in advance if this sounds like a naive question, as Angular and Typescript are not my strong suits. I am assisting a friend with an issue that I can't seem to overcome.

I have an array of players that includes details such as first name and kit color. My goal is to simply sort/group the array by kit color under specific H1 tags.

import { Component, VERSION } from '@angular/core';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  Players = [
    {
      FirstName: 'Vader',
      KitColour: 'Blue',
    },
    {
      FirstName: 'Darth',
      KitColour: 'Red',
    },
    {
      FirstName: 'Yeeeeet',
      KitColour: 'Red',
    },
    {
      FirstName: 'New',
      KitColour: 'Blue',
    },
  ];
  constructor() {
    this.Players.sort((a, b) => {
      var colorA = a.KitColour.toLowerCase();
      var colorB = b.KitColour.toLowerCase();
      if (colorA < colorB) {
        return -1;
      }
      if (colorA > colorB) {
        return 1;
      }
      return 0;
    });
    const sliceArray = (arr, chunkSize) => {
      const result = [];
      for (let i = 0; i < arr.length; i += chunkSize) {
        const chunk = arr.slice(i, i + chunkSize);
        result.push(chunk);
      }
      return result;
    };
    sliceArray(this.Players, 2);
    console.log(this.Players);
  }
}
<div class="container" *ngFor="let player of Players">
  <div class="{{ player.KitColour }}">
    <h1>{{ player.KitColour }} Team</h1>
    <p>{{ player.FirstName }}</p>
  </div>

My Desired Output: https://i.stack.imgur.com/yK7P2.png

Is there a way to sort them once under a single H1 tag, either Blue or Red based on Kit Color? Example: Red Player Names..

Blue Player Names..

Answer №1

To effectively address this issue, consider revising your object structure either within a service or component.

groupByKitColor = (array: any) => {
    return array.reduce((prev, actual) => {
      prev[actual.KitColour] = prev[actual.KitColour] || [];
      prev[actual.KitColour].push(actual);
      return prev;
    }, Object.create(null));
  };

This approach allows for grouping players based on the number of colors added in the future. Simply apply your CSS class afterwards.

Check out this StackBlitz example: https://stackblitz.com/edit/angular-ivy-dyflwe?file=src%2Fapp%2Fapp.component.html

PS: In terms of best practices, sorting logic should be implemented in the OnInit Lifecycle rather than in the constructor (as per convention), and variable names should follow camelCase notation ;)

Answer №2

Arrange array based on KitColour attribute

  TeamMembers = [
    {
      FirstName: 'Vader',
      KitColour: 'Blue',
    },
    {
      FirstName: 'Darth',
      KitColour: 'Red',
    },
    {
      FirstName: 'Yeeeeet',
      KitColour: 'Red',
    },
    {
      FirstName: 'New',
      KitColour: 'Blue',
    },
  ].sort((a, b) => a.KitColour.localeCompare(b.KitColour));

and integrate this html code snippet

   <div *ngFor="let player of TeamMembers; let index = index">
    <h1 *ngIf="0 === index">{{ player.KitColour }}</h1>
    <h1 *ngIf="0 !== index && player.KitColour! !== TeamMembers[index - 1].KitColour">
      {{ player.KitColour }}
    </h1>

    <p>{{ player.FirstName }}</p>
  </div>

Answer №3

When the ngFor directive is placed on the parent div, you will end up with a number of h1 elements equal to the length of the array (one for each element). To optimize your code, consider moving the color extraction outside of ngFor and use ngIf conditionally to display the names based on colors.

Answer №4

If you are certain that no additional colors will be added, a helpful approach is to divide your array into two separate arrays: one for each color.

Once this separation has been made, create individual div elements for each color and place the *ngFor loop within your p tag like so:

<div class="container">
  <div class="Red">
    <h1>Red Team</h1>
    <p *ngFor="let redPlayer of RedPlayers">{{ redPlayer.FirstName }}</p>
  </div>
  <div class="Blue">
    <h1>Blue Team</h1>
    <p *ngFor="let bluePlayer of BluePlayers">{{ bluePlayer.FirstName }}
  </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

Utilizing React SSR to dynamically import components based on API response

I am currently working on a SSR React app using the razzle tool, with the server running on the express framework. My goal is to dynamically load React components based on the value included in an API response. My folder structure looks like this: views ...

jQuery and Easy Dialog

My jQuery Model window has a form inside. Even though I have set autoOpen to false in my dialog, the fields are still visible when the page is created. All forms are contained within a div. This is what my dialog code looks like: $("#dialog-form").dial ...

Issue with iframe's size not displaying correctly

<body> <script> document.write("<iframe id='theframe' src='http://www.website.com?testvr=" + testvr + " height='900' width='500'></iframe>"); </script> </body> The iframe is added, but ...

Is there a way to adjust the border color of my <select> element without disrupting the existing bootstrap CSS styling?

In my Bootstrap (v4.5.3) form, the select options appear differently in Firefox as shown in the image below: https://i.sstatic.net/3suke.png Upon form submission, I have JavaScript code for validation which checks if an option other than "-- Select an Op ...

Locating characters within an array of Charactes

For an assignment, I am tasked with identifying substrings within an array. Here is the array provided: char DNA[] = {'A', 'G', 'C', 'G', 'G', 'G', 'A', 'C', 'C', & ...

The Angular Ivy strictTemplates error message states that the type 'Event' cannot be assigned to the type 'InputEvent' parameter

I'm feeling lost trying to figure out what's wrong with this code snippet: <input #quantity type="number" matInput formControlName="quantity" (input)="onQuantity($event, i)" placeholder="Quantity"/> onQuantity(event: InputEvent, i: number ...

Difficulty encountered when attempting to invoke a public function that makes use of a private function in TypeScript

I'm relatively new to TypeScript and I've been trying to replicate a pattern I used in JavaScript where I would expose functions through a single object within a module (like "services"). Despite my efforts, I'm facing some issues when attem ...

How to customize font styles in AngularJS

I'm attempting to modify the font style of an element when a certain variable is true. Within my controller, I have a variable that retrieves its value. My objective is to adjust the font style depending on this value using ng-style. I've exhau ...

What causes the low Performance score of a default NextJS Application with no content?

Just started experimenting with my initial Next.js project. Upon generating a new project using create-next-app, I decided to test its performance with the web application 'Lighthouse'. Surprisingly, although most other metrics scored above 90, ...

When clicking on absolute URLs, Angular Router Navigation Events are not triggered

Hey there! I need to reset certain values when we navigate away from the current page by clicking on an anchor link with an absolute URL. I've tried using the router events code below, but it only works for relative URLs and not absolute URLs. Is the ...

UTF-8 characters not displaying correctly in Python 3 when received through WebSocket?

I am encountering an issue with sending a JavaScript unicode star character. When interpreted by Python, the unicode characters are being displayed as the letter â, both in the console and log file. Furthermore, other unicode characters also seem to be ...

Inaccurate Guild Member Filtering

Recently, I've been working on creating a unique member counter for my server. The goal is to accurately count the total number of members in the server, excluding bots, and counting only bots as well. However, when I attempt to display these counts i ...

Methods for invoking a function from a separate .js file within React Native Expo

I'm new to using React and I've come across a challenge: In my Main.js file, there is a button: import * as React from 'react'; import { StyleSheet, Text, View, SafeAreaView, Pressable, Alert } from 'react-native'; import { M ...

Vue has issued a warning stating that the type check for the "eventKey" prop has failed. The expected type was a String or Number, but an Array was provided instead. Additionally, it is advised to

The code I am currently using is producing the following errors in the console output: [Vue warn]: Avoid using non-primitive value as key, use string/number value instead. [Vue warn]: Invalid prop: type check failed for prop "eventKey". Expected String, ...

How can I easily implement basic password protection on a straightforward Next.js web app hosted on Vercel?

Adding a simple password validation step to a dashboard that only a select few would access. The data is not highly sensitive, but some basic protection is desired to limit unauthorized access. While not expecting targeted attacks from hackers, the goal is ...

You cannot reassign NodeJS global variables

Currently, I am in the process of writing unit tests for code that utilizes a JavaScript library. This particular library sets a global variable if it does not already exist using the following pattern: var GLOBAL_VAR = GLOBAL_VAR || {} While this method ...

Angular - Is there a specific type for the @HostListener event that listens for scrolling on the window?

Encountering certain errors here: 'e.target' is possibly 'null'. Property 'scrollingElement' does not exist on type 'EventTarget'. What should be the designated type for the event parameter in the function onWindow ...

Include a tab button within a vertical tab list using Angular Material

I have utilized Angular Material to create a vertical tab, and I would like to incorporate an Add Tab button within the tab listing itself. Currently, when I add the button, it appears at the bottom of the layout instead. For reference, you can access the ...

Experiencing ERR_TOO_MANY_REDIRECTS while using Next.js with Vercel and a Custom Domain through Cloudflare

I'm having trouble getting my Next.js project set up on Vercel with a custom domain managed through Cloudflare. Despite configuring the DNS and SSL settings correctly, I keep seeing a net::ERR_TOO_MANY_REDIRECTS error when trying to access my site at ...