מודל תגובה ושגיאת סוג ב-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,
}
});
});
