プログラミングでエラーメッセージが出たとき、特に英語で羅列されているのを見ると、なえてしまうかと思いますが、今日はそんな中の一つ、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が出たときは、バインディングする値を毎回生成していないか確認してみると、意外と簡単になおせるかもしれません。