Model odpovede a chyba typu v Angular TypeScript


Na lokálnej aplikácii MEAN stack používajúcej NodeJS server moja odozva koncového bodu vracia pole príspevkov:

{
  "message": "Posts fetched successfully!",
  "posts": [
    {
     "_id": "618b22ff9e50776ed377c4eb",
     "title": "aaaaaaaaaaaaaa",
     "body": "xxxxxxxxxxxxx",
     "__v": 0
    },
  ]
}

Angular služba s modelom odpovede:

export interface PostResponse {
  message: string;
  posts: Post;
}

  getPosts(): Observable<PostResponse> {
   return this.http.get<PostResponse>(this.postsUrl + '/api/posts');
  }

PostComponent injektuje vyššie uvedený Postservice:

    export interface Post {
      id: number;
      title: string;
      body: string;
    }


export class PostsComponent implements OnInit {
  posts: Post[] = [];
  constructor(private postService: PostService) {}    

    ngOnInit() {
      this.postService
       .getPosts()
       .pipe(
         map((data) => {
             console.log('data : ', data.posts._id);  // vide #1
          return {
           id: data.posts.id,                       // _id error <HERE>
           title: data.posts.title,
           content: data.posts.body,
         };
       })
      ).subscribe((response) => {
       this.posts = response;                          // error <HERE>
       console.log('posts updated : ', this.posts);
    });

}

Otázka.

Q-1 : Na mojom komponente, keď mapujem údaje odpovede, požadovaná vlastnosť je data.posts.id, namiesto data.posts._id, ale prúd údajov je: #1 { "_id": "618b22ff9e50776ed377c4eb", "title": "aaaaaaaaaaaaaa", "body": "xxxxxxxxxxxxx", "__v": 0 },

ak použijem _id, dostanem chybu Vlastnosť '_id' neexistuje na type 'Post'

Je to kvôli môjmu rozhraniu PostResponse?

_id pochádza z mojej Mongo databázy, predpokladal som, že musím vynútiť transformáciu dát odpovede, aby zodpovedali štruktúre front-endu, kde nepoužívam _ID, ale ID.

Q-2: pri subscribe, pri this.posts=response dostávam chybu:

Typ '{ id: number; title: string; content: string; }' postráda nasledujúce vlastnosti typu 'Post[]': length, pop, push, concat a ďalších 26.ts(2740)

Odpoveď č. 1

Q1: Áno, je to kvôli vášmu rozhraniu PostResponse, ktoré používate v getPosts(). Atribut Posts v tomto rozhraní odkazuje na rozhranie Post, čo znamená, že všetky atribúty v objektoch posts sú z rozhrania Post. Opravte to takto:

export interface Post {
  _id: string;
  title: string;
  body: string;

}

Q2: Mapujete json odpoveď z PostResponse a nie hodnotu atribútu 'post', takže to vráti objekt namiesto poľa. Skúste toto:

 this.postService
   .getPosts()
   .pipe(
     map((data) => {
      return data.posts.map(v => {
       _id: v._id,                       
       title: v.title,
       content: v.body,
      })
   })
  ).subscribe((response) => {
   this.posts = response;  
});

A nastav typ atribútu príspevku na pole v PostResponse :

export interface PostResponse {
  message: string;
  posts: Post[];
 }

Odpoveď č. 2

Z toho, čo som pochopil, sú vaše rozhrania nesprávne.

export interface PostResponse {
  message: string;
  posts: Post[];
}

export interface Post {
  _id: string;
  title: string;
  body: string;
}

Zdá sa, že to sú správne rozhrania.

Na získanie údajov by ste mali:

this.postService
       .getPosts()
       .subscribe((response) => {
         this.posts = response?.posts; 
   });

Alebo

this.postService
           .getPosts()
           .subscribe((response) => {
             this.posts = response?.posts?.map(res => {
               return {
                 _id: res.id,
                 title: res.title,
                 body: res.body,
               }
             }); 
       });