【Angular/MongoDB/エラー】オブジェクトデータの表示
※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。
【目次】
背景
LaravelでMongoDBからデータを取得して、Angularで表示させようとしたら、[object Object]が表示されました。
これを解決するのにとても苦労したので、その原因とデータの表示方法を備忘録として書きます。
本当はネストが深い場合でのオブジェクトデータの表示に苦労したのですが、私の場合はそもそもオブジェクトデータについて間違った認識をしていていたので、今回はネストがない場合でのオブジェクトデータの表示から詳しく書いていきます。
ネストが深い場合の記事は明日以降に書きます。
【2/6 追記】
ネストが深いオブジェクトデータの表示について記事を書きました。
【Angular/MongoDB】ネストが深いオブジェクトの表示 - 大田区から発信するゆるゆる日記
オブジェクトの表示
問題の内容
以下の環境で開発を行っています。
- Angular
- Laravel
- MongoDB
MongoDBにあるオブジェクトをLaravelで取得し、Angularでリッチに表示させようとしていました。
Angularのcomponent.htmlで以下のコードを書いたら、サイトでは[object Object]が表示されていました。
※今回はcomponent.ts内にオブジェクトのデータを入れています。本来であれば、service.tsでLaravelからデータを取得しているので、component.ts内に下記のapiDataデータは不要です。
component.ts
"updated_at":"2019-04-10 13:54:10"}
component.html
[object Object]
原因
- オブジェクトはそのままでhtmlに表示できない
- オブジェクトと配列は違う
- オブジェクトと連想配列は場合によっては同意義
総じると、オブジェクトと配列を同じと捉えていたのが、解決までに時間がかかってしまった原因でした。
オブジェクトはそのままではhtmlに表示をさせることができません。
また、ややこしいことにオブジェクトはjavascriptオブジェクトや連想配列とも呼ばれているのですが、JavaScriptではそれらも含めてオブジェクトと呼んでいいみたいです。文献によって言い方が違ったのでややこしかった・・・
JavaScript: 配列(array)とオブジェクト(object)の違い
解決方法
オブジェクトデータを配列データやjson文字列に変換すれば幸せになれそうです。
Angularを使っているなら、4のKeyValuePipeを使用するのが良さそうです。
※オブジェクトデータは上記に記載した【問題の内容】と同じとします。
1.Keyを指定(objectName.propertyName)
通常のJavaScript変数と同じように、オブジェクトのプロパティ値(Value)はドット表記、もしくはブラケット (角括弧) 記述法でプロパティ名(Key/propertyName)を指定してアクセスします。
例
or
結果
or
154
ネストが深いと、これは上手くいかないかもしれません。
あと、プロパティ名(Key)を取得することができません。
2.パイプjson
オブジェクト(javascriptオブジェクト)になっているデータをJSON文字列に変換してくれます。
プロパティ名(Key)やプロパティ値(Value)、括弧なども全て文字列に変換します。
例
結果
このままでは使えないですね。
3.Object.keysメソッド(Angular6以下)
Object.keys() - JavaScript | MDN
このメソッドはオブジェクトデータのプロパティ名(Key)を配列にして返してくれます。
つまり、プロパティ名だけの配列を生成してくれます。
Object.keysメソッドを使うには、Object.keysメソッドを一度変数に入れる必要があります。
Object.keysメソッドの引数には、メソッドを入れることもできるので、とても便利なメソッドだと思います。
例
component.ts
}
component.html
結果
page_id:79
user_id:1548
text:this is the first message to be sent by joe
created_at:2019-04-10 13:54:10
updated_at:2019-04-10 13:54:10
合わせて、Object.valuesメソッドも覚えているといいかもです。
Object.values() - JavaScript | MDN
使用頻度が多そうなら、パイプ化してしまうのもいいかと思います。
(弊社ではそうしています)
4.KeyValuePipe(Angular6.1以降)
Angular6.1以降から登場したパイプです。
CommonModuleのインポートが必要です。
プロパティ名を「key」と「value」とする配列を作り、それをオブジェクトにして返します。プロパティ値には引数のプロパティ名(Key)とプロパティ値(Value)が入ります。
{ "key": "created_at", "value": "2019-04-10 13:54:10" }
{ "key": "id", "value": 154 }
{ "key": "page_id", "value": 79 }
{ "key": "text", "value": "this is the first message to be sent by joe" }
{ "key": "updated_at", "value": "2019-04-10 13:54:10" }
{ "key": "user_id", "value": 1548 }
例
module.ts
component.html
結果
id:154
page_id:79
text:this is the first message to be sent by joe
updated_at:2019-04-10 13:54:10
user_id:1548
順番が変わる…なんでだろ?
5.for...inループ
すみません、あまり使わなさそうだったので省略します!
6.Object.getOwnPropertyNamesメソッド
Object.getOwnPropertyNames() - JavaScript | MDN
すみません、あまり使わなさそうだったので省略します!
7.JSON.stringify
JSON.stringify() - JavaScript | MDN
AngularでJavaScriptオブジェクトをJSON形式に変換するには?(json):Angular TIPS - @IT
パイプjsonに相当します。
すみません、あまり使わなさそうだったので省略します!
なお、オブジェクト(プロパティ)の値がundefined、またはfunction型(=メソッド)の場合は、変換の対象外です。
今後に向けて
ネストが深いともう一手間必要なんですが、この記事の内容が分かっていればさほど手間取ることはないと思います。
ネストが深い場合についてはまた今度書きます。
※コードをちょっと試す時はこれ便利。
The online code editor for web apps. Powered by Visual Studio Code. - StackBlitz
参考
素晴らしい記事に感謝いたします。
https://tutorialmore.com/questions-991072.htm