[AngularJS] Infinite $digest Loopのエラーがでたらどうするか

プログラミングでエラーメッセージが出たとき、特に英語で羅列されているのを見ると、なえてしまうかと思いますが、今日はそんな中の一つ、AngularJSのエラーについて紹介します。Error: $rootScope:infdig Infinite $digest Loopです。エラーが起きたときにまず大切な心構えは焦らないこと。私も初めて見たときは、なんじゃこりゃ、もう駄目だわ。と思ったけど、ゆっくりエラーについて読んでみて、リンクをクリックしてみたら、親切にエラーの解決方法について記述してありました。それがこちらのページ。ただ英語だし、よくわからない方もいると思うので、このエラーが起こった時の解決方法を紹介したいと思います。

エラーの理由

このエラーが起こる理由は他にもあるみたいですが、私が直面したのはこれ。

One common mistake is binding to a function which generates a new array every time it is called

リンク先にコードの例まで載せてあるので、とても分かりやすいですね。簡単に訳すと、

テンプレートにバインディングする関数で、毎回、配列を新しく作るとエラーになりますよ。

だそうです。テンプレートなんていう単語は、本文にはないんですが、私の場合はTypeScriptのテンプレートに表示させているので少し意訳しました。

解決方法

export class TmpCtrl implements ng.IComponentController
{
    private users: IUser[] = [];

    // この関数をテンプレートから呼び出すようにする。
    // ここで生成した配列をリターンしてしまうとエラーが起きてしまいます。
    public getUsers(): IUser[]
    {
        temp = ? // 新しい値を代入する。
        this.users.length = 0;
        angular.extend(this.users, temp)    
        return this.users;
    }
}

全てのソースコードは載せていませんが、ポイントは、プライベートメンバーとして、テンプレートに渡したいオブジェクトをもつ。そして、呼び出すときには毎回初期化して、そこに新しいオブジェクトをコピーします。こうするとthis.usersの配列はいつもあって新しく生成されないのでエラーになりません。パズルみたいで面白いですね!

さいごに

エラーが起こるとまずは落ち着いて問題を見てみましょう。私はいつも慌てて、もうプログラマーやめたいと思ってしまいますけど、冷静にグーグルすればだいたいは答えがあるので、できるだけ落ち着くようにしています。このInfinite $digest Loopが出たときは、バインディングする値を毎回生成していないか確認してみると、意外と簡単になおせるかもしれません。

最新情報をチェックしよう!