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