【Angular Utilities】指定日時までのカウントダウンを表示する Date Time Countdown を作った

みんな大好き Moment.js と、v6 系が登場した RxJS を使って、カウントダウンタイマーを作った。

入力値を moment オブジェクトにブチ込んで、moment#valueOf() を使って UNIX 時刻を取得。コレを「未来日時 - 現在日時」と減算して、その結果を moment.duration() に渡すと、2つの日数の差分を出力できるようになる。

あとは画面の入力フォームと出力したい形式に合わせてゴリゴリ調整するだけ。

コレが「2つの時刻間の差を求めて表示する」処理になるのだが、今回はコレを1秒間隔で定期的に実行し直したい。そうすることで、1秒ずつカウントダウンしていく画面を作りたいのだ。

Vanilla JS なら setInterval でやるところだが、今回は RxJS の interval を使う。

import { interval, Subscription } from 'rxjs';

@Component( /* 中略 */ )
export class DateTimeCountdownComponent implements OnInit, OnDestroy {
  /** タイマー */
  private timer: Subscription;
  
  /** 画面初期表示時の処理 */
  public ngOnInit(): void {
    // 初期処理など…
    
    // タイマーをセットする
    this.timer = interval(1000).subscribe(() => {
      // 1秒おきに繰り返したい処理
      this.calcDuration();
    });
  }
  
  /** 画面遷移時の処理 */
  public ngOnDestroy(): void {
    // タイマーを止める
    if(this.timer) {
      this.timer.unsubscribe();
    }
  }
}

こんな感じ。

Observale.interval を参考にしたのはこの記事なのだが、RxJS v6 になって import が変わっていた。

コチラを見ると、interval のインポートの仕方が以下のように変わっていることが分かる。

// RxJS v5 まで
import 'rxjs/add/observable/interval';

// RxJS v6 から
import { interval } from 'rxjs';

Angular Update Guide にも RxJS の変更があれやこれや登場するが、何でこんな変更が入ったんだろ?よく分からないが、とりあえずコレでできた。