AngularJSを初めたての頃、アホみたいなはまり方をした。 わかってしまえば当たり前なだけに、調べても分かりにくかったので恥さらしに記録する。
こんなミスを起こすと、気付くまでは動かない意味がわからなかった。
- scriptタグを忘れる
- モジュールを毎回生成してしまう
- パラメータのIDを変えてしまった
scriptタグを忘れる
こんなエラーが出る。当たり前だけどなんで未定義になるのかわからなかった。
angular.js:11607Error: [ng:areq] Argument 'HogeCtrl' is not a function, got undefined
コントローラの名前を変えたりすると、起こりがち。あと、ファイルをフォルダに移動したりすると。
index.htmlにscriptタグ書きましょう
モジュールを毎回生成してしまう
モジュール名の意味もよくわかってなかった。
Error: [$injector:unpr] Unknown provider: CoolServiceProvider <- CoolService <- SomeCoolCtrl
こんなエラーとかでたりする。
ググって出てくるサンプルコードが、たいてい下の形になっていて真似していろんなファイルでangular.moduleの第二引数まで書いてしまった。
angular.module('SomeCoolApp', ['coolModule']) .config(...) .controller(...) .factory('CoolService', function(){ coolFunction(); });
これをすると毎回モジュールを生成してしまうから、解決するためにモジュール名をファイルごとに変えたりして、 泥沼にはまっていった。
Yeomanのgenerate-angularを使っていると、コントローラ、サービス、フィルタ、ディレクティブなどを全部別のファイルに分けてくれるので、 自動生成された部分を下手にいじるとはまる。
ググって出てきたコードのどこが必要なのか見極める必要がある。
こんな感じに書くと動く。
angular.module('SomeCoolApp') .factory('CoolService', function(){ coolFunction(); });
パラメータのIDを変えてしまった
これはチーム開発してる時。
ルーティングを別のメンバが調整してくれたときにパラメータの名前を変えていた。 サービスで参照するときに名前がなくて怒られる。
その怒られる場所がモックで500エラー。
例
変更前。ItemLoaderが$resourceのgetをつかってアイテムを1件取得する。MultiItemLoaderが$resourceのqueryを使って一覧取得する。 APIはRESTに従っていて、item.jsonで一覧取得、item/id.jsonで1件取得できる状態です。
angular.module('SomeCoolApp') .config(['$routeProvider', function($routeProvider) { $routeProvider .when('/item/:itemId', { resolve: { item: ['ItemLoader', function(ItemLoader) { return new ItemLoader(); }] }, templateUrl: 'views/item/view.html', controller: 'ItemViewCtrl' }) .when('/item', { resolve: { items: ['MultiItemLoader', function(MultiItemLoader) { return new MultiItemLoader(); }] }, templateUrl: 'views/item.html', controller: 'ItemCtrl' });
変更後。 item/:itemId
が item/:id
になる。
angular.module('SomeCoolApp') .config(['$routeProvider', function($routeProvider) { $routeProvider .when('/item/:id', { resolve: { item: ['ItemLoader', function(ItemLoader) { return new ItemLoader(); }] }, templateUrl: 'views/item/view.html', controller: 'ItemViewCtrl' }) .when('/item', { resolve: { items: ['MultiItemLoader', function(MultiItemLoader) { return new MultiItemLoader(); }] }, templateUrl: 'views/item.html', controller: 'ItemCtrl' });
結果。
ItemLoaderで$route.current.params.itemIdが参照できないので、$resourceのgetにidが渡らない
→REST APIの1件取得ではなく一覧取得が呼ばれる
→サーバーでエラー。
これも見つけにくかったので記録しておこうかと。