angular - Subscribe() ส่งค่ากลับ "complete:() => void; 'complete' ถูกประกาศที่นี่ นี่หมายความว่าอะไร?
ฉันกำลังติดตามบทเรียนสอน และผ่านการตรวจสอบและตรวจสอบซ้ำ ฉันมั่นใจ 100% ว่าโค้ดของฉันเหมือนกับที่อาจารย์ใช้ เรากำลังสร้างแอปหน้าเดียวแบบง่ายใน Angular ซึ่งโดยสมมติแล้วเกี่ยวข้องกับ Typescript
ฉันค่อนข้างมั่นใจว่าคลาสภายนอกทั้งหมดถูกเขียนอย่างถูกต้อง และ VS Code ไม่พบข้อผิดพลาดอื่นใดในโค้ดที่เขียน ยกเว้นสคริปต์ต่อไปนี้ในไฟล์ feed.component.ts แนวคิดคือการกำหนดแอตทริบิวต์ listPost (ประเภทอาร์เรย์และคลาส Post[]) ซึ่งรับรายการวัตถุโพสต์ที่อยู่ในที่อยู่ที่ระบุในคลาส PostService
เพื่อที่จะให้ชัดเจนมากขึ้น ปัญหาที่ฉันกำลังเผชิญอยู่คือในฟังก์ชัน findPosts() ซึ่งมันบอกว่ามีข้อผิดพลาดที่ชี้ว่า “complete() => void” (ซึ่งฉันไม่รู้ว่ามันหมายความว่าอะไร) สิ่งหนึ่งที่ทำให้ฉันกังวลคือสิ่งนี้ถูกเขียนเหมือนกับในไฟล์ของอาจารย์ทุกประการ ความแตกต่างเพียงอย่างเดียวคือเขาใช้ Typescript v. 3.9.2 ในขณะที่ฉันใช้ v. 4.3.2 ฉันสงสัยว่าสิ่งนี้อาจเป็นปัญหา เพราะจากที่ฉันค้นคว้ามา typescript มีปัญหาเยอะเมื่อแปลความหมายเวอร์ชันต่าง ๆ
import { Component, OnInit } from '@angular/core';
import { PostService } from '../service/post.service';
import { Post } from '../model/Post'
@Component({
selector: 'app-feed',
templateUrl: './feed.component.html',
styleUrls: ['./feed.component.css']
})
export class FeedComponent implements OnInit {
private listPost: Post[];
constructor(private postService: PostService) {
this.listPost = []
}
ngOnInit(): void {
this.findPosts()
}
findPosts() {
this.postService.getPosts()
.subscribe(
(data: Post[]) => {this.listPost = data} );
}
}คำตอบ #1
ฉันเป็นผู้เขียนคำถามนี้และฉันจะตอบที่นี่ว่าฉันแก้ไขมันอย่างไร เพื่อให้สิ่งนี้อาจช่วยใครบางคนในอนาคต
โอเค ดังนั้น ฉันคิดว่านี่เกี่ยวข้องกับเวอร์ชันของ Typescript บางอย่าง ไม่รู้ว่าทำไม
ก่อนอื่น นี่คือวิธีที่โค้ดบทเรียนทำงานโดยใช้ Typescript 3.9:
export class FeedComponent implements OnInit {
listPost: Post[];
constructor(private postService) { }
ngOnInit(): void {
this.postService.getPosts().subscribe(
(data: Post[]) => this.listPost = data )}}โอเค ดังนั้น ความแตกต่างเพียงอย่างเดียวที่จำเป็นต้องนำไปใช้ในโค้ดนี้ ได้ถูกนำไปใช้อยู่แล้วเมื่อฉันสร้างคำถาม ซึ่งก็คืออันนี้:
export class FeedComponent implements OnInit {
listPost: Post[];
constructor(private postService: PostService) {
this.listPost = []} // <--- THIS WAS INCLUDED
ngOnInit(): void {
this.postService.getPosts().subscribe(
(data: Post[]) => this.listPost = data )}}ดังนั้น ดูเหมือนว่าใน Typescript 4 ตอนนี้คุณจะต้องกำหนดค่าเริ่มต้นให้ตัวแปรใน constructor นั่นคือสาเหตุแรกของข้อผิดพลาด แต่ทำไมมันถึงยังคงคืนค่า Error อยู่? คำตอบอยู่ในไฟล์ post.services เมื่อฉันสร้างคำถาม ไฟล์ post.services ถูกเขียนแบบนี้:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class PostService {
constructor(private http: HttpClient) { }
public getPosts() {
return this.http.get('http://localhost:3000/posts')
}
}มันต้องถูกเขียนใหม่แบบนี้:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs'; // <--- THIS WAS INCLUDED
import { Post } from '../model/Post'; // <--- THIS WAS INCLUDED
@Injectable({
providedIn: 'root'
})
export class PostService {
constructor(private http: HttpClient) { }
public getPosts(): Observable<Post[]> { // <--- THIS WAS MODIFIED
return this.http.get<Post[]>('http://localhost:3000/posts')
}
}ฉันจริง ๆ ไม่รู้ว่าทำไมเรื่องนี้ถึงจำเป็น ฉันหาคำตอบโดยการลองผิดลองถูก ดูจากบริบทอื่น ๆ ที่คืนค่า error เหมือนกัน ดูเหมือนว่าการระบุประเภทของค่าที่คืนมาจากเมธอด get เป็น Observable กลายเป็นสิ่งที่จำเป็น ฉันเห็นว่าไวยากรณ์เป็นแบบนั้น ดังนั้นฉันจึงค้นพบว่าฉันก็ต้อง import โมดูล Post ของฉันและโมดูล Observable นี้เข้าไปในไฟล์บริการด้วย
สุดท้าย ในโมดูล Post ฉันยังต้องเริ่มต้นแอตทริบิวต์ JSON ในคอนสตรัคเตอร์ด้วย
คำตอบ #2
บางทีนี่อาจถูกต้อง
async findPosts() {
await this.postService.getPosts()
.subscribe((data: Post[]) => this.listPost = data);
}
