Animating Angular on the table row element

I am currently displaying a table with a list of items that are updated via polling using an http get request to the server. The response is rendered only if there have been changes in the data.

My goal is to add animations to the rows of the table and trigger the animation only for new rows. Currently, the animation is triggered every time the response updates and the component re-renders, affecting all rows instead of just the new ones.

In my main.component.ts, I pass down observables to child components. These include the event$ stream with the array of events to display and newSeenPlatformIds$ that emits the maximum value of IDs when there is a change. This is used to trigger the animation for new rows based on this number.

ngOnInit() {
    // Events rendered in the table
    this.events$ = timer(0, 5000).pipe(
      switchMap(() => this.eventsService.fetchLastEvents()),
      distinctUntilChanged(
        (curr, prev) =>
          Math.max(...curr.map(currItem => currItem.id)) === Math.max(...prev.map(prevItem => prevItem.id))
      )
    );
    // Animation triggered every time a new ID is emitted
    this.newSeenPlatformIds$ = this.events$.pipe(
      map(events => Math.max(...events.map(event => event.id))),
      distinctUntilChanged()
    );
  }

This is the table component where the animation logic resides:

import { Component, OnInit, Input } from '@angular/core';
import { Observable } from 'rxjs/internal/Observable';
import { Event } from 'src/app/shared/interfaces/event';
import { trigger, style, transition, animate } from '@angular/animations';
import { tap } from 'rxjs/operators';

@Component({
  selector: 'app-last-events-grid',
  templateUrl: './last-events-grid.component.html',
  styleUrls: ['./last-events-grid.component.scss'],
  animations: [
    trigger('newRowAnimation', [
      transition('* <=> *', [style({ opacity: 0 }), animate('1000ms', style({ opacity: 1 }))])
    ])
  ]
})
export class LastEventsGridComponent implements OnInit {
  @Input() events$: Observable<Event[]>;
  @Input() newSeenPlatformIds$: Observable<number>;
  newSeenPlatformId: number;
  triggerAnimation = false;

  constructor() {}

  ngOnInit() {
    this.newSeenPlatformIds$.pipe(tap(id => console.log(id))).subscribe(id => {
      this.newSeenPlatformId = id;
      this.triggerAnimation = true;
    });
  }
}

Lastly, here's the template code:

<div class="flex justify-center">
  <table class="w-full mx-10">
    <thead class="text-gray-500">
      <tr>
        <th class="cell-main"></th>
        <th class="cell-main">DESCRIPTION</th>
        <th class="cell-main">TIME</th>
        <th class="cell-main">READER</th>
        <th class="cell-main">STATE</th>
        <th class="cell-main">NEXT CHECK</th>
        <th class="cell-main">READINGS LEFT</th>
      </tr>
    </thead>
    <tbody>
      <tr
        [@newRowAnimation]="triggerAnimation && event.id === newSeenPlatformId"
        [ngClass]="{ 'row-nok': event.estado === false }"
        class="rounded overflow-hidden shadow-lg text-xl text-gray-500"
        app-event-item
        *ngFor="let event of events$ | async"
        [event]="event"
      ></tr>
    </tbody>
  </table>
</div>

Answer №1

If anyone else encounters a similar problem, I managed to resolve it by exploring the "trackBy" option mentioned by @tsiro. I simply followed their advice and it fixed the issue:

solution

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

Mastering the implementation of opaque tokens in Angular 2

Hey there! I'm having trouble with opaquetoken, is there something I missed? Check out my Plunk example here. Here's the relevant code snippet from app.ts: export const SbToken = new OpaqueToken('myToken'); const testfile = 'Hel ...

Guide to accessing and modifying attributes of Ionic components in TypeScript file

I am curious about how to manipulate the properties or attributes of an Ionic component from a TypeScript file. For example, if I have an input component on my HTML page: <ion-item> <ion-input type="text" [(ngModel)]="testText"></ion ...

Having trouble with installing Bootstrap in Angular 5

My journey with Bootstrap began by executing the command below: npm install --save bootstrap The installation was a success, and I proceeded to incorporate the CSS as follows: "styles": [ "../node_modules/bootstrap/dist/css/bootstrap.min.css", ...

Avoid saying the same thing more than once

Within my Typescript class, I have the following structure: class C { #fsm (...) startFoo(name: string) { this.#fsm.send('FOO', name) return this } startBar(name: string) { this.#fsm.send('BAR', name) return th ...

Next.js TypeScript project encountered an issue: "An error occured: 'TypeError: Cannot read property 'toLowerCase' of undefined'"

I am currently developing a Next.js TypeScript project and am facing a perplexing runtime error. The error message reads: TypeError: Cannot read property 'toLowerCase' of undefined This error is triggered in my code when I try to invoke the toLo ...

I'm facing an issue where the ion-select component is not displaying the selected value when

Whenever I apply formcontrolname to an ion-select element, the initially selected value does not appear. It only becomes visible when I interact with the select element or use setTimeout(): html: <form [formGroup]="formGroup"> ...

Issues with the visibility of inlined styles within the Angular component library

After developing a custom library with components for an Angular 4 application, I encountered an issue where the CSS styling from the components was not being applied when using them in an application. Although the functionality worked fine, the visual asp ...

Angular 2 eliminates the need for nesting subscriptions

Is there a way to streamline nested subscriptions like the code snippet below? I want to extract values from the subscription for better organization, but using a global variable won't work because the subscription hasn't received the value yet. ...

Resolving Modules: Using NPM to Install the Typescript Package Directly from Github

Recently, I decided to branch out and customize an existing npm package built in TypeScript to cater specifically to my unique requirements. I discovered that I could also install packages from GitHub branches using npm without any issues. However, after ...

Invalidity of types occurs when dispatching data to redux

My reducer code is as follows: import { profileAPI } from '../api/api' import shortid from 'shortid' const ADD_POST = 'profile/ADD-POST' const SET_USER_PROFILE = 'profile/SET_USER_PROFILE' const SET_STATUS = 'p ...

Guide on Validating Several Email Addresses in a React Form using Angular 4

I need to input 50 email addresses with the same domain name (gmail.com). Currently, I am using a Reactive form but the code I have implemented is not working as expected. https://stackblitz.com/edit/angular-wfwfow If anyone could assist me with this, I ...

How to Hide Warning Messages in Angular NPM Package for Production Environment

Seeking advice on a coding issue I'm facing. Currently, I am in the process of creating an npm package for angular / angular material, which involves implementing some checks. If a developer fails to pass a specific argument to my function, the funct ...

Leveraging Ignorable Fields in Angular 2 Reactive Forms

Can Angular 2's reactive forms support adding ignorable fields? For example, consider the following Form: this.form = new FormGroup({ subTasks: new FormArray([]), }); Each subTask requires user input and the solution is stored in the FormArray. ...

What are the reasons behind memory leaks and decreased rendering speed when I exit and then reopen a React component (specifically Material-Table)?

I have been working on a basic React example for learning purposes, and I incorporated the use of material-table in one of my components. However, I noticed that each time I change pages and reopen the component (unmount and mount), the rendering speed of ...

Why is Angularfire2 failing to save the data it fetches?

It seems that I am struggling to accomplish what I need because of a lack of knowledge on the proper method. My goal is to save a connection between a user and a school (which is also a user), and then retrieve some image URLs from the school user in a new ...

Can you explain the significance of ?. in Angular 5?

While I understand that product.id == 1 ? stuff : not stuff simplifies to choosing "stuff" if the id is 1 and "not stuff" otherwise, I am unsure about the meaning of the following code: product?.id.name ...

Error Type: TypeError when using Mongoose's FindOneAndUpdate function

I am encountering difficulties while trying to implement a findOneAndUpdate query. //UserController UserDAO ['findOneAndUpdate'](userId, {& ...

What is the best method to obtain access to the controls of an item within FormArray?

My goal is to assign an invalid class to the parent div of each input based on its validity status. In the form, I can control the input fields like this: <div class="form-group focus" [ngClass]="!recipeForm.controls.name.valid ? ...

Modify/remove table using a popup window

My goal was to include edit and delete buttons within a table. When these buttons are clicked, a popup window opens allowing us to modify the values and then update them in the table using Angular. ...

merging pictures using angular 4

Is there a way in Angular to merge two images together, like combining images 1 and 2 to create image 3 as shown in this demonstration? View the demo image ...