Issues arise when attempting to sort items in Angular8 using the addEventListener method

Trying to implement a sorting function in my table by clicking on the column header has proven to be challenging. The desired behavior is that on the first click, items in the column should be sorted in ascending order, and on the second click, they should be sorted in descending order.

Below is the HTML code snippet:

<thead>
  <tr>
    <th (click)="sorting('FirstName')" class="sorting" role="columnheader" tabindex="0" aria-controls="sample_1" rowspan="1" colspan="1" aria-label="Ime i prezime : activate to sort column ascending">
      First Name
    </th>                
    <th (click)="sorting('Email')" class="sorting" role="columnheader" tabindex="0" aria-controls="sample_1" rowspan="1" colspan="1" aria-label="Email : activate to sort column ascending">
      Email
    </th>
    <th (click)="sorting('Username')" class="sorting" role="columnheader" tabindex="0" aria-controls="sample_1" rowspan="1" colspan="1" aria-label="Username: activate to sort column ascending">
      Username
    </th>                 
    <th>
      Actions
    </th>
  </tr>
</thead>   

And here is the corresponding TypeScript code:

sorting(sortBy) {
  this.sortBy = sortBy;
  let tableHeaderItems = Array.from(document.querySelectorAll('.sorting'));

  const handleClick = (e) => {
    e.preventDefault();
    e.stopPropagation();
    console.log(e.currentTarget.classList);
    if (e.currentTarget.classList.contains('sorting_asc')) {
      e.currentTarget.classList.remove('sorting_asc');
      e.currentTarget.classList.add('sorting_desc');
      this.sortDirection = "desc";
    }
    else if (e.currentTarget.classList.contains('sorting_desc')) {
      e.currentTarget.classList.remove('sorting_desc');
      e.currentTarget.classList.add('sorting_asc');
      this.sortDirection = "asc";
    }
    else {
      tableHeaderItems.forEach(node => {
        node.classList.remove('sorting_asc');
        node.classList.remove('sorting_desc');
      });
      e.currentTarget.classList.add('sorting_asc');
      this.sortDirection = "asc";
    }
  }

  tableHeaderItems.forEach(node => {
    node.addEventListener('click', handleClick)
  });

  this.service.getAll(this.sortBy, this.sortDirection);
}

Encountering a problem where the function is only triggered once with each click, but const handleClick is being called multiple times. Initially, clicking on the column does not trigger anything inside const handleClick. Subsequent clicks result in inconsistent behavior - the function is called twice, three times, or more depending on the number of clicks. Any insights into why this might be happening would be greatly appreciated.

Answer №1

Avoid using the DOM for this task.


<thead>
  <tr>
    <th (click)="sorting('FirstName')"
      class="sorting"
      [ngClass]="sortBy === 'FirstName' ? { 'sorting_asc': sortDirection === 'asc', 'sorting_desc':  sortDirection === 'desc' } : null">
      First Name
    </th>
    <th (click)="sorting('Email')"
      class="sorting"
      [ngClass]="sortBy === 'Email' ? { 'sorting_asc': sortDirection === 'asc', 'sorting_desc':  sortDirection === 'desc' } : null">
      Email
    </th>
    <th (click)="sorting('Username')"
      class="sorting"
      [ngClass]="sortBy === 'sorting' ? { 'sorting_asc': sortDirection === 'asc', 'sorting_desc':  sortDirection === 'desc' } : null">
      Username
    </th>
    <th>
      Actions
    </th>
  </tr>
</thead>
  sorting(sortBy) {
    this.sortBy = sortBy;
    this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
    this.service.getAll(this.sortBy, this.sortDirection);
  }

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

Angular asynchronous unit test ends too soon

I am facing an issue with my Angular unit test using Jasmine-Karma. The test seems to finish prematurely without completing all the steps. Can someone please assist me with this problem? Output: LOG: '{"a":"b"}' LOG: '1' LOG: 'Fi ...

If the value is null, pass it as is; if it is not null, convert it to a date using the

I am currently facing an issue regarding passing a date value into the rrule plugin of a fullCalendar. Here is the snippet of code in question: Endate = null; rrule: { freq: "Daily", interval: 1, dtstart: StartDate.toDate ...

Automatically increase the version with Yarn auto Version Bump

My package.json file uses a 4-digit version format like "version": "1.3.0-0". When I run the command yarn version --prerelease on my Windows system, it correctly shows: info Current version: 1.3.0-0 info New version: 1.3.0-1 However, ...

Why does the type checking for props in vue.js keep failing despite my use of "Object as PropType<GeographicCoordinate | null>"?

Scenario: Utilizing vue.js (^3.2.13) with Typescript and Composition API in Visual Studio Code File type.ts: export class GeographicCoordinate { latitude: number; longitude: number; altitude?: number; constructor(latitude: number, longitude: numb ...

Exploring the Angular Structure: Utilizing External Libraries in Feature Modules

Currently, I am in the process of building a new angular application that includes various feature modules. As part of this project, I am integrating Material Design components. I am seeking advice on the best approach for importing Material Design modules ...

Obtaining the value from a TypeScript hashmap: Using a getter function or setting a

Looking to create a simple getter for retrieving a value from an object with string keys, or returning a default value of the same type when necessary. This situation arises frequently when working with Maps in Typescript. The main focus is on accessing to ...

Resolving Angular 4 issue by delivering Observable of an array of strings

The error "Type 'Observable<{ "aa": any; "dd": any; "cc": any; }>' is not assignable to type 'Observable'." is popping up in my Angular 4 project. How can I resolve this issue with the syntax? Any suggestions on fixing this err ...

Loading Data in an IONIC List as You Scroll

Is there a way in IONIC using native components to generate a dynamic list? What I mean is being able to load the initial data and rows, display them, and then continue loading additional data as the user scrolls to avoid long loading times for all data ...

step-by-step guide on integrating Spring Boot API with Angular using Apache

I'm looking to make an API call from my Angular file (profile.service.ts) to a Spring Boot backend. private baseUrl = '/users'; constructor(private http: HttpClient) { } getProfile(id: number): Observable<Object> { return ...

Automating email testing for Azure Graph-built applications: A step-by-step guide

I am exploring options to streamline the email testing process for an application developed with Azure Graph integration. Currently, I am leveraging playwright and typescript for other testing purposes within the application. One of the key functionaliti ...

The 'event' parameter is being implicitly assigned an 'any' type

I'm currently utilizing TypeScript within an Electron application but I am encountering the following error message: Parameter 'event' implicitly has an 'any' type.ts(7006) Below is the code snippet in question. Any suggestions ...

Is it possible to modify a single value in a React useState holding an object while assigning a new value to the others?

In my current state, I have the following setup: const [clickColumn, setClickColumn] = useState({ name: 0, tasks: 0, partner: 0, riskFactor: 0, legalForm: 0, foundationYear: 0 }) Consider this scenario where I only want to update ...

Is the runTest.ts class in the vscode-test setup ever utilized in the project? Its purpose remains unclear even in the example project

Being a novice to Typescript, JavaScript, and VScode Extensions I have set up a vscode-test following the guidelines provided here: https://code.visualstudio.com/api/working-with-extensions/testing-extension#custom-setup-with-vscodetest Based on the hel ...

applying specific attributes to the mdButton based on certain conditions

Is there a way to make a button highlighted with an accent color when it is active? For example: <button md-button *ngFor="let item of items" [attr.color]="item.caption == activeItem ? 'accent' : ''"> Or maybe: <button md-b ...

How can Angular use separate package.json files for different environments?

I'm curious if it's possible to have a unique package.json file for each of my environments (production, testing, and QA). Currently, each environment has different code snapshots with varying package versions. Our environments are built using Je ...

Using Typescript with Protractor for Dropdown Menus

As a newcomer to Protractor, I am looking to automate the selection of a dropdown. While I have some knowledge in JavaScript, I am currently working with typescript. Can someone advise me on how to select the dropdown option based on the text provided? Fo ...

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 ...

Failure of Ngx-translate to propagate to subcomponents

Since I have implemented my translate module in the shared/header.module.ts file, it mainly serves the purpose of handling language switching for the entire application. In header.module.ts: @NgModule({ imports: [ TranslateModule.forRoot({ lo ...

Is there a way to specify object keys in alignment with a specific pattern that allows for a variety of different combinations

I am seeking a way to restrict an object to only contain keys that adhere to a specific pattern. The pattern I require is: "{integer}a+{integer}c". An example of how it would be structured is as follows: { "2a+1c": { // ... } } Is there a ...

Assignment of type 'Object' is incompatible with type in new HttpClient / HttpGetModule implementation within Angular

After following the angular tutorial, I decided to test out the new httpClient.Get method. However, it seems that no matter what, it always returns results of type Object. // HttpClient getHeroes2 () { this.http.get<Hero[]>(this.heroesUrl) ...