

AngularのHttpclientModuleを使ってExpressからデータを取得して表示する処理を実装しています。  
GETで受け取り値を表示する際に以下のエラーが出ます。  
このエラーを解消するにはどうすればいいでしょうか？

[code]

    Property 'id' does not exist on type 'number | Comment | (() => string) | (() => string) | (() => Comment | undefined) | ((...items: Comment[]) => number) | { (...items: ConcatArray<Comment>[]): Comment[]; (...items: (Comment | ConcatArray<...>)[]): Comment[]; } | ... 27 more ... | (() => { ...; })'.
      Property 'id' does not exist on type 'number'.
    
    9                 <h4 class="media-heading">{{ comment.value.id | json }}</h4>
    
[/code]

**・該当のコード**  
型定義

[code]

    export interface Comment{
      
      comments: [
        {
          id: number,
          message: string,
          }
        ]
    }
    
[/code]

**comment.service.ts**

[code]

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpRequest, HttpErrorResponse } from '@angular/common/http';
    import { catchError } from "rxjs/operators";
    import { Observable } from 'rxjs';
    import { Comment } from '../models/comment';
    import { of } from "rxjs";
    
    @Injectable({
      providedIn: 'root'
    })
    export class CommentService {
      private base_url: string = 'http://localhost:3000'
      comments!: Comment
    
      constructor(private http: HttpClient) { }
    
      getComments(): Observable<Comment>{
        return this.http.get<Comment>(`${this.base_url}/comments`) // get通信
        .pipe(
          catchError(this.handleError<Comment>('getComments'))
        );
      }
    
      private handleError<T>(operation = 'operation', result?: T) {
        return (error: any): Observable<T> => {
          // TODO: リモート上のロギング基盤にエラーを送信する
          console.error(error); // かわりにconsoleに出力
          // 空の結果を返して、アプリを持続可能にする
          return of(result as T);
        };
      }
      
    
    }
    
[/code]

・ **app.commponet.ts**  
ngOnInit()内の返す値の型がおかしいのかなと予想します

[code]

    import { Component, OnInit } from '@angular/core';
    import { Observable } from 'rxjs';
    import { ApiService, Item} from './service/api.service';
    import { Comment } from './models/comment';
    import { CommentService } from './service/comment.service'
    // import { Comment } from './class/comment'
    import { NgForm } from '@angular/forms';
    
    @Component({
      selector: 'ac-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit {
      title = 'web-app';
      
      comes!: Comment[]
      // public comments$!: Observable<Comment>
      form!: NgForm
    
    
      constructor(private api:ApiService, private comment: CommentService){}
    
      ngOnInit(): any{
        this.comment.getComments().subscribe((res: any) => {
           this.comes = res.comments
           console.log(this.comes)
        })
        
      }
    }
    
[/code]

・ **app.component.html**

[code]

    <div *ngFor="let comment of comes | keyvalue">
            
              <div class="media">
                <div class="media-body">
                  <div class="d-flex w-100 justify-content-between">
                    <h4 class="media-heading">{{ comment.value.message | json }}</h4>
                    <small class="media-date">{{ comment | json}}</small>
                  </div>
                </div>
     </div>
    
[/code]

comment | jsonの中身

[code]

    { "id": 1, "message": "おはようございます", "createdAt": "2022-02-17T23:47:57.011Z", "updatedAt": "2022-02-22T03:45:49.555Z" }
    
[/code]

・追記  
エラー全文

[code]

    Property 'message' does not exist on type 'KeyValue<string, number | Comment | (() => string) | (() => string) | (() => Comment | undefined) | ((...items: Comment[]) => number) | { (...items: ConcatArray<Comment>[]): Comment[]; (...items: (Comment | ConcatArray<...>)[]): Comment[]; } | ... 27 more ... | (() => { ...; })>'.
    
[/code]

comment | jsonの中身が`{ "key": "0", "value": { "id": 1, "message": "おはようございます",
"createdAt": "2022-03-06T10:01:29.781Z", "updatedAt":
"2022-03-06T10:01:29.790Z" } }`  
なので、{{comment.value.message}}で表示しようとすると以下のエラー

[code]

    Property 'message' does not exist on type 'number | Comment | (() => string) | (() => string) | (() => Comment | undefined)
    
[/code]

・修正箇所

[code]

    export class CommentService {
      private base_url: string = 'http://localhost:3000'
      comments!: ResponseComment
    
      constructor(private http: HttpClient) { }
    
      getComments(): Observable<ResponseComment>{
        return this.http.get<ResponseComment>(`${this.base_url}/comments`)
        .pipe(
          catchError(this.handleError<ResponseComment>('getComments'))
        );
      }
    
[/code]

・型定義

[code]

    export interface Comment {  
      id: number
      message: string
      createdAt: number
      user_id: number
    }
    
    export interface ResponseComment {  
      comments: Array<Comment>
    }
    
[/code]


CC BY-SA 4.0
2022-03-05T03:44:10.093
86693
2022-03-08T02:43:56.717
2022-03-07T23:07:40.267
39431
39431
question
angularjs
AngularでProperty 'message' does not exist on type 'Observable<any>.というエラーが表示される


`app.commponet.ts` の `comes` は `Comment[]`
の型だと宣言しているので以下のようなCommentの配列を期待するようになっています

[code]

    comes = [
    {
      comments: [
        {
          id: number,
          message: string,
          }
        ]
    },
    {
      comments: [
        {
          id: number,
          message: string,
        }
      ]
    }
    ]
    
[/code]

実際は `{ id: number, message: string }`
配列を期待されているようなのでAPIレスポンスとモデルでインターフェイスを分けたほうが良いでしょう

[code]

    export interface Comment {  
      id: number
      value: {
        message: string
      }
    }
    
    export interface ResponseComment {  
      comments: Array<Comment>
    }
    
[/code]

インターフェイス変更後、CommentServiceの型を変更します。（他にも細かい修正が発生するかもしれません）

[code]

    // comment.service.ts
    export class CommentService {
    // 省略
      getComments(): Observable<ResponseComment>{
        return this.http.get<ResponseComment>(`${this.base_url}/comments`)
        .pipe(
          catchError(this.handleError<ResponseComment>('getComments'))
        );
      }
    // 省略
    }
    
[/code]

[code]

    <div *ngFor="let comment of comes | keyvalue">
            
              <div class="media">
                <div class="media-body">
                  <div class="d-flex w-100 justify-content-between">
                    <h4 class="media-heading">{{ comment.value.message }}</h4>
                    <small class="media-date">{{ comment | json}}</small>
                  </div>
                </div>
     </div>
    
[/code]


CC BY-SA 4.0
2022-03-07T06:52:32.077
86728
2022-03-08T02:43:56.717
2022-03-08T02:43:56.717
298
298
86693
answer