0

I recently created a countdown timer component in my Angular web application by referring Mwiza's article.

This timer component was then inserted as a child in the component where the timing supposed to display. By such the countdown display as expected when run in desktop and Android mobile devices with various browsers. However, failure happened on iOS mobile devices (tested on iPhone 6, iPhone 6S, iPhone 13, and iPad with cross browsers including Safari, Chrome, Edge, and Firefox), in which all the timing values (day, hour, minute, and second) showed as 'NaN' other than the actual countdown time e.g., 'NaNd NaNh NaNm NaNs'. The expected correct display should be e.g., '30d 14h 45m 35s' as properly showed on Android and desktop devices.

Here is the countdown timer code of the timer component:

export class CountdownTimerComponent implements  OnInit, OnDestroy {  
  targetDate: string;
  subscription: Subscription;
  milliSecondsInASecond = 1000;
  hoursInADay = 24;
  minutesInAnHour = 60;
  SecondsInAMinute = 60;

  timeDifference: any;
  secondsToDday: any;
  minutesToDday: any;
  hoursToDday: any;
  daysToDday: any; 

  constructor(private adminService: AdminService) { }        

  ngOnInit() {
    this.getTargetDate();
    this.subscription = interval(1000)
        .subscribe(x => { this.getTimeDifference(); });
  }

  getTargetDate() {
    this.adminService.getSysConfigs().subscribe((resp: any[]) => {
      this.targetDate = resp.find(s => s.name === 'SingleCardItem').client;
    // here the targetDate is in format '2022-10-9'
    })
  }

  private getTimeDifference () {
    let dDay = new Date(this.targetDate);
    this.timeDifference = dDay.getTime() - new  Date().getTime();
    this.allocateTimeUnits(this.timeDifference);
  }

  private allocateTimeUnits (timeDifference) {
    this.secondsToDday = Math.floor((timeDifference) / (this.milliSecondsInASecond) % this.SecondsInAMinute);
    this.minutesToDday = Math.floor((timeDifference) / (this.milliSecondsInASecond * this.minutesInAnHour) % this.SecondsInAMinute);
    this.hoursToDday = Math.floor((timeDifference) / (this.milliSecondsInASecond * this.minutesInAnHour * this.SecondsInAMinute) % this.hoursInADay);
    this.daysToDday = Math.floor((timeDifference) / (this.milliSecondsInASecond * this.minutesInAnHour * this.SecondsInAMinute * this.hoursInADay));
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

}

template code:

<div class="timer">
    <span id="days"> {{daysToDday}}d </span>
    <span id="hours"> {{hoursToDday}}h </span> 
    <span id="minutes"> {{minutesToDday}}m </span>
    <span id="seconds"> {{secondsToDday}}s </span>
</div>

Debugging failed to detect any error and the server did not log any issue either when the countdown timer failed to display those timing values. Can anyone help point out what could be the root-cause and how the issue could be fixed?

canbrian
  • 109
  • 1
  • 3
  • 13
  • Are you using `parseInt()` or `parseFloat()` functions anywhere? It could be that you are passing strings to these functions when numbers are expected. `NaN` might be because of that. – Nikhil Sep 08 '22 at 23:52
  • @Nikhil, the issue is very likely related to date type. Fortunately, TS/JS Date() itself functions to convert string "2022-10-08" to date. And the current code does display the countdown time properly on desktop and Android mobile devices. – canbrian Sep 09 '22 at 00:19
  • 1
    I see. Check out this answer, it might help: https://stackoverflow.com/a/5324266/2924577 – Nikhil Sep 09 '22 at 00:36
  • Thanks for Nikhil stressing on parsing strings to get the right date. I fixed the issue by structuring a new date from the string other than simply trusting Date() function. Now, the timer works as expected crossing all platforms. – canbrian Sep 09 '22 at 00:47

0 Answers0