Q:

angular - how to loop count down with current time

I have an array of times (futuretimes) so I need to show a countdown timer in MM:SS format in decrement order by comparing with the current time(HH:MM). so when the timer finishes then it will jump to find the next highest timer from new current HH:MM  
How to do this ?
    const futuretimes = ["5:00 AM" , "5:30 AM" , "5:45 AM" , "6:00 AM" , "6:15 AM" , "6:30 AM" , "6:40 AM" , "6:50 AM" , "7:00 AM" , "7:08 AM" , "7:16 AM" , "7:24 AM" , "7:35 AM" , "7:40 AM" , "7:45 AM" , "7:50 AM" , "7:55 AM" , "8:00 AM" , "8:05 AM" , "8:10 AM" , "8:15 AM" , "8:20 AM" , "8:25 AM" , "8:30 AM" , "8:34 AM" , "8:38 AM" , "8:42 AM" , "8:46 AM" , "8:50 AM" , "8:54 AM" , "8:58 AM" , "9:02 AM" , "9:06 AM" , "9:10 AM" , "9:15 AM" , "9:20 AM" , "9:25 AM" , "9:30 AM" , "9:35 AM" , "9:40 AM" , "9:45 AM" , "9:50 AM" , "9:55 AM" , "10:00 AM" , "10:06 AM" , "10:12 AM" , "10:18 AM" , "10:26 AM" , "10:34 AM" , "10:40 AM" , "10:50 AM" , "11:00 AM" , "11:10 AM" , "11:20 AM" , "11:30 AM" , "11:40 AM" , "11:50 AM" , "12:00 PM" , "12:10 PM" , "12:20 PM" , "12:30 PM" , "12:40 PM" , "12:50 PM" , "1:00 PM" , "1:10 PM" , "1:20 PM" , "1:30 PM" , "1:40 PM" , "1:50 PM" , "2:00 PM" , "2:10 PM" , "2:20 PM" , "2:30 PM" , "2:40 PM" , "2:50 PM" , "3:00 PM" , "3:10 PM" , "3:20 PM" , "3:30 PM" , "3:40 PM" , "3:50 PM" , "4:00 PM" , "4:08 PM" , "4:16 PM" , "4:24 PM" , "4:32 PM" , "4:40 PM" , "4:45 PM" , "4:50 PM" , "4:55 PM" , "5:00 PM" , "5:05 PM" , "5:10 PM" , "5:14 PM" , "5:18 PM" , "5:22 PM" , "5:26 PM" , "5:30 PM" , "5:34 PM" , "5:38 PM" , "5:42 PM" , "5:46 PM" , "5:50 PM" , "5:55 PM" , "6:00 PM" , "6:05 PM" , "6:10 PM" , "6:15 PM" , "6:20 PM" , "6:25 PM" , "6:30 PM" , "6:35 PM" , "6:40 PM" , "6:45 PM" , "6:50 PM" , "6:55 PM" , "7:00 PM" , "7:05 PM" , "7:10 PM" , "7:15 PM" , "7:20 PM" , "7:25 PM" , "7:30 PM" , "7:35 PM" , "7:40 PM" , "7:45 PM" , "7:50 PM" , "7:55 PM" , "8:00 PM" , "8:06 PM" , "8:12 PM" , "8:18 PM" , "8:24 PM" , "8:30 PM" , "8:36 PM" , "8:42 PM" , "8:48 PM" , "8:54 PM" , "9:00 PM" , "9:08 PM" , "9:16 PM" , "9:24 PM" , "9:32 PM" , "9:40 PM" , "9:50 PM" , "10:00 PM" , "10:15 PM" , "10:30 PM" , "10:45 PM" , "11:00 PM"];

Expected output:
E.g: Suppose if the current time HH:MM is 5:31AM  then the countdown timer should pick a next highest HH:MM time comparing with the current time HH:MM  from above-defined array(i.e futuretimes) which is just highest time, so in this example it should pick 5:45 AM from array because it is next highest value from current time(5:31AM) and then  countdown timer should be shown  and once the current countdown timer finishes then it will take next highest from array as compared to the new  current time etc.
I tried to get the current time in seconds and but stuck how to make for loop between these arrayoftime and pick the highest one to start timercountdown:
    const currentMinute = new Date().getMinutes();
    const currenthour = new Date().getHours(); 

    const totalseconds=3600*currenthour +60*currentMinute;//current time in seconds

    // now stuck how to do further

A:

Here's one implementation in angular using observables.
Stackblitz: https://stackblitz.com/edit/angular-sbosff
<small>Now</small>
<p>{{ now$ | async | date:'h:mm:ss a' }}</p>
<hr>
<small>Next Time</small>
<ng-container>
  <p>{{ (nextTime$ | async)?.time }}</p>
</ng-container>
<hr>
<ng-container>
  <small>Countdown to Next</small>
  <p>{{ timeToNext$ | async }}</p>
</ng-container>
<hr>
<small>All Times</small>
<ng-container *ngFor="let timeOption of futuretimes">
  <p>{{ timeOption }}</p>
</ng-container>

import { Component } from '@angular/core';
import { Observable, interval, combineLatest } from 'rxjs';
import { startWith, map } from 'rxjs/operators';

interface StringTimeWithDate {
  time: string;
  asDate: Date;
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  now$: Observable<Date>;
  nextTime$: Observable<StringTimeWithDate>;
  timeToNext$: Observable<string>;
  futuretimes = [
    '5:00 AM',
    '5:30 AM',
    '5:45 AM',
    '6:00 AM',
    '6:15 AM',
    '6:30 AM',
    '6:40 AM',
    '6:50 AM',
    '7:00 AM',
    '7:08 AM',
    '7:16 AM',
    '7:24 AM',
    '7:35 AM',
    '7:40 AM',
    '7:45 AM',
    '7:50 AM',
    '7:55 AM',
    '8:00 AM',
    '8:05 AM',
    '8:10 AM',
    '8:15 AM',
    '8:20 AM',
    '8:25 AM',
    '8:30 AM',
    '8:34 AM',
    '8:38 AM',
    '8:42 AM',
    '8:46 AM',
    '8:50 AM',
    '8:54 AM',
    '8:58 AM',
    '9:02 AM',
    '9:06 AM',
    '9:10 AM',
    '9:15 AM',
    '9:20 AM',
    '9:25 AM',
    '9:30 AM',
    '9:35 AM',
    '9:40 AM',
    '9:45 AM',
    '9:50 AM',
    '9:55 AM',
    '10:00 AM',
    '10:06 AM',
    '10:12 AM',
    '10:18 AM',
    '10:26 AM',
    '10:34 AM',
    '10:40 AM',
    '10:50 AM',
    '11:00 AM',
    '11:10 AM',
    '11:20 AM',
    '11:30 AM',
    '11:40 AM',
    '11:50 AM',
    '12:00 PM',
    '12:10 PM',
    '12:20 PM',
    '12:30 PM',
    '12:40 PM',
    '12:50 PM',
    '1:00 PM',
    '1:10 PM',
    '1:20 PM',
    '1:30 PM',
    '1:40 PM',
    '1:50 PM',
    '2:00 PM',
    '2:10 PM',
    '2:20 PM',
    '2:30 PM',
    '2:40 PM',
    '2:50 PM',
    '3:00 PM',
    '3:10 PM',
    '3:20 PM',
    '3:30 PM',
    '3:40 PM',
    '3:50 PM',
    '4:00 PM',
    '4:08 PM',
    '4:16 PM',
    '4:21 PM',
    '4:32 PM',
    '4:40 PM',
    '4:45 PM',
    '4:50 PM',
    '4:55 PM',
    '5:00 PM',
    '5:05 PM',
    '5:10 PM',
    '5:14 PM',
    '5:18 PM',
    '5:22 PM',
    '5:26 PM',
    '5:30 PM',
    '5:34 PM',
    '5:38 PM',
    '5:42 PM',
    '5:46 PM',
    '5:50 PM',
    '5:55 PM',
    '6:00 PM',
    '6:05 PM',
    '6:10 PM',
    '6:15 PM',
    '6:20 PM',
    '6:25 PM',
    '6:30 PM',
    '6:35 PM',
    '6:40 PM',
    '6:45 PM',
    '6:50 PM',
    '6:55 PM',
    '7:00 PM',
    '7:05 PM',
    '7:10 PM',
    '7:15 PM',
    '7:20 PM',
    '7:25 PM',
    '7:30 PM',
    '7:35 PM',
    '7:40 PM',
    '7:45 PM',
    '7:50 PM',
    '7:55 PM',
    '8:00 PM',
    '8:06 PM',
    '8:12 PM',
    '8:18 PM',
    '8:24 PM',
    '8:30 PM',
    '8:36 PM',
    '8:42 PM',
    '8:48 PM',
    '8:54 PM',
    '9:00 PM',
    '9:08 PM',
    '9:16 PM',
    '9:24 PM',
    '9:32 PM',
    '9:40 PM',
    '9:50 PM',
    '10:00 PM',
    '10:15 PM',
    '10:30 PM',
    '10:45 PM',
    '11:00 PM'
  ];
  futureTimesAsDate: StringTimeWithDate[];

  constructor() {
    // map time to date and ensure sort ascending
    this.futureTimesAsDate = this.futuretimes
      .map(time => ({ time, asDate: this.timeStringToDate(time) }))
      .sort((a, b) => (a.asDate > b.asDate ? 1 : -1));

    this.now$ = interval(1000).pipe(
      startWith(null),
      map(() => new Date())
    );

    this.nextTime$ = this.now$.pipe(
      map((now: Date) => this.futureTimesAsDate.find(timeDate => timeDate.asDate > now))
    );

    this.timeToNext$ = combineLatest(this.now$, this.nextTime$, (now, nextTime) => {
      if (!now || !nextTime) {
        return null;
      }

      const diff = nextTime.asDate.valueOf() - now.valueOf();
      const millisPerSec = 1000;
      const millisPerMin = millisPerSec * 60;

      const min = Math.floor(diff / millisPerMin);
      const msLeftover = Math.floor(diff % millisPerMin);
      const secLeftover = Math.ceil(msLeftover / millisPerSec);

      const formattedMin = min < 10 ? `0${min}` : min;
      const formattedSec = secLeftover < 10 ? `0${secLeftover}` : secLeftover;
      const minMsToNext = `${formattedMin}:${formattedSec}`;

      return minMsToNext;
    });
  }

  ngOnInit() {}

  private timeStringToDate = dateString => {
    const [time, period] = dateString.split(' ');
    const [hour, minutes] = time.split(':').map(numString => Number(numString));
    const hourOutOf24 = period.toLowerCase() === 'pm' && hour !== 12 ? hour + 12 : hour;

    const dateForDateString = new Date();
    dateForDateString.setHours(hourOutOf24, minutes, 0, 0);

    return dateForDateString;
  }
}

