0

I have a table with multiple rows. Need to display timer, which will indicate the remaining time in n Days, x Hrs, y Min and z Secs.

I'm able to calculate remaining time using

REF Link.

and I'm calling same function in column using {{myXYZFunction()}}

its calculating date and time as expected

but I think function call is lagging,

many time seconds are getting updated after 2 seconds, and it is not showing smooth transition for seconds like 1,2,3,4... 60 Its somewhat like 1,2,4,6,8,10,12,13,14,15,17... 60

1 Answers1

0

Performance wise you generally want to avoid having function calls directly in the as this is called every change detection cycle. Performace tips

A much better approach would to update a member variable to the values you wish to display. For example:

@Component({
  selector: 'app-component',
  template: '
    <table>
      <thead>
        <tr>
          <th>Date</th>
          <th>Time left</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="time in times">
          <td>{{time.date}}</td>
          <td>{{time.counter | async}}</td>
        </tr>
      </tbody>
    </table>
  '
})
export class MyComponent {
  public times;

  constructor() {
    // Creates an observable that is triggers every second.
    // Observable.interval(1000).subscribe(_ => this.time = myXYZFunction());
  }

  setupTimes() {
    const rawTimes = this.getTimes(); 
    this.times = [];
    rawTimes.forEach(tm => this.times.push({date: tm, counter: this.setupCounter(tm)});
  }

  setupCounter(time) {
    return Observable.interval(1000).pipe(map(_ => myXYZFunction(time)));
  }

  /**
  * Collect all the dates that should be displayed from the backend or use a  static array.
  */
  getTimes(): number[]{
    return [];
  }
}

In this way you control that your function is only called when it needs to be called. Reducing unnecessary load and removing the UI lag you're observing.

EDIT

As noted that the counter and date will be displayed as a table the example has been adapted. Please note that we form a object out of the date and countdown timer. None the less what is trying to be achieved here is quite costly and likely will lag beyond a few dates. Additionally we take advantage of the async pipe to not have to worry about unsubscribing. Unless you truly must have to the second accuracy, I would increase the counter to once every few seconds or minutes if possible. This will greatly reduce the load on the browser.

setupCounter(time) { // Updated every minute.
  return Observable.interval(60000).pipe(map(_ => myXYZFunction(time)));
}
Ish
  • 71
  • 6