I have have a service in Angular, which calls data from an API. So when I am trying to display the data it is not displaying?
Service
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable, of, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
@Injectable()
export class ApiService {
api: string = 'https://newsapi.org/v2/top-headlines?country=gb&category=entertainment&apiKey=8ee8c21b20d24b37856fc3ab1e22a1e5';
constructor(
private http: HttpClient,
) { }
getAll(): Observable<any> {
return this.http.get(this.api)
.pipe(
catchError(this.handleError)
);
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
console.log(error.error.message)
} else {
console.log(error.status)
}
return throwError(
console.log('Something is wrong!'));
};
}
Component.ts
import { Component, OnInit } from '@angular/core';
import { ApiService } from './api.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
public data = [];
public noData: any;
public results = [];
constructor(
private api: ApiService
){ }
getAll() {
this.api.getAll().subscribe((results) => {
this.data = results.results;
console.log('JSON Response = ', JSON.stringify(results));
})
}
ngOnInit() {
}
}
JSON response structure
{
"status":"ok",
"totalResults":70,
"articles":[
{
"source":{
"id":null,
"name":"Thesun.co.uk"
},
"author":"Mary Gallagher",
"title":"Holly Willoughby breaks down in tears on This Morning as she meets disabled boy who speaks against all odds - The Sun",
"description":"",
etc etc
HTML
<div *ngFor="let news of data">
<h3>{{news.json}}</h3>
</div>
Where Am I going wrong?
articles
is a property of data, so you have to loop data.articles
Try like this:
<ng-container *ngFor = "let news of data?.articles">
<h3>{{news.title}}</h3>
</ng-container>
Another option:
TS:
this.data = results.articles; // here now you have list of all articles
HTML:
*ngFor="let news of data"
Working Demo
When you ask for a "correct" way, it is commonly recommended to avoid subscriptions in component when you don't have to. Prefer async
pipe instead.
import { Component, OnInit } from '@angular/core';
import { ApiService } from './api.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
public data$: Observable<Data[]>;
constructor(
private api: ApiService
){ }
ngOnInit() {
this.data$ = this.api.getAll();
}
}
<ng-container *ngIf="data$ | async as data; else pending">
<div *ngFor="let article of data.articels">
<h3>{{news.json}}</h3>
</div>
</ng-container>
<ng-template #pending>
<div>pending</div>
</ng-container>
Advantage: You never forget to unsubscribe, you have easy control over pending state
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With