Angular 8中无法通过Observable获取API返回的data.all数据求助
Hey there! Let’s break down what’s going wrong and fix it step by step.
First, the core issue: the API you’re working with returns an object containing an all field that holds the array of facts, not directly an array of IFact items. Your current code assumes the response is a raw array, which is why you’re hitting those errors.
Step 1: Fix your interface definitions
You need a top-level interface to match the actual API response structure, while keeping your IFact interface for individual fact items:
export interface IFact { _id: string; text: string; type: string; user: { _id: string; name: { first: string; last: string; }; }; upvotes: number; userUpVoted: string; // Changed from literal '' to string type for better type safety } // This matches the API's actual response shape (an object with an `all` array) export interface IFactResponse { all: IFact[]; }
Step 2: Update your FactService to return the correct type
Adjust the return type of getFacts() to use the new IFactResponse interface—this tells TypeScript exactly what structure to expect from the API:
@Injectable({ providedIn: 'root' }) export class FactService { // Use the actual API URL you mentioned instead of the local placeholder private _url = 'https://cat-fact.herokuapp.com/facts'; constructor(private http: HttpClient) { } getFacts(): Observable<IFactResponse> { return this.http.get<IFactResponse>(this._url); } }
Step 3: Adjust your component to extract the all array
Now you can safely access data.all in your component to get the list of facts:
export class FactComponent implements OnInit { public facts: IFact[] = []; // Type your array for clearer type safety constructor(private _factService: FactService) { } ngOnInit() { this._factService.getFacts() .subscribe( data => { this.facts = data.all; // Correctly pull the facts array from the response console.log(this.facts); }, err => console.error('Failed to load facts:', err) ); } }
Step 4: Fix your template (HTML)
You used ng-repeat which is an AngularJS directive—Angular 8 uses *ngFor instead. Plus, your table structure was invalid (<td> wrapping <tr>). Here’s the corrected template:
<table> <thead> <tr> <th>Fact ID</th> <th>Fact Text</th> </tr> </thead> <tbody> <!-- Loop over table rows, not table cells --> <tr *ngFor="let fact of facts"> <td>{{ fact._id }}</td> <td>{{ fact.text }}</td> </tr> </tbody> </table>
Why your original errors happened:
- TypeScript warning: Your service was returning
Observable<IFact[]>, so TypeScript treateddataas an array. Arrays don’t have anallproperty, hence the warning. - Template error: You used the wrong directive (
ng-repeatinstead of*ngFor) and had invalid table structure. Plus,this.factswas initially set to the full response object (not the array), so Angular couldn’t resolve thefactvariable during rendering.
内容的提问来源于stack exchange,提问作者Guido Caffa

