מודל תגובה ושגיאת סוג ב-Angular TypeScript


באפליקציית MEAN מקומית המשתמשת בשרת NodeJS, תגובת נקודת הקצה שלי מחזירה מערך של פוסטים:

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

שירות Angular עם מודל תגובה:

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

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

רכיב הפוסט מזריק את שירות הפוסט שלמעלה:

    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);
    });

}

שאלה.

שאלה 1: ברכיב שלי, כשאני ממפה את נתוני התגובה, ה-prop הנדרש הוא data.posts.id, במקום data.posts._id, אבל נתוני הזרם הם: #1 { "_id": "618b22ff9e50776ed377c4eb", "title": "aaaaaaaaaaaaaa", "body": "xxxxxxxxxxxxx", "__v": 0 },

אם אני משתמש ב-_id, אני מקבל שגיאה Property '_id' אינה קיימת על סוג 'Post'

האם זה בגלל הממשק שלי PostResponse?

_id מגיע ממסד הנתונים שלי במונגו, הנחתי שעלי לכפות את המרת נתוני התגובה כך שיתאימו למבנה של צד הלקוח שבו אני לא משתמש ב-_ID אלא ב-ID.

שאלה-2: על ה-subscribe, על this.posts=response אני מקבל שגיאה:

Type '{ id: number; title: string; content: string; }' חסר את הפרופרטיז הבאים מהסוג 'Post[]': length, pop, push, concat, ועוד 26 נוספים.ts(2740)

תשובה #1

שאלה 1: כן, זה בגלל ממשק ה-PostResponse שלך שאתה משתמש בו ב-getPosts(). התכונה Posts בממשק הזה מתייחסת לממשק Post, מה שאומר שכל התכונות באובייקטים של posts הן מממשק Post. תקן את זה עם:

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

}

שאלה 2: אתה ממפה את תגובת ה-JSON מ-PostResponse ולא את ערך התכונה 'post', אז זה יחזיר אובייקט במקום מערך. נסה את זה:

 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;  
});

ועשה את סוג המאפיין של הפוסט למערך ב-PostResponse :

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

תשובה #2

ממה שהבנתי, הממשקים שלכם שגויים.

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

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

נראה שאלו הם הממשקים הנכונים.

כדי לקבל את הנתונים עליך:

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

או

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