Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to display data from Rest Api in Angular

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?

like image 528
Sole Avatar asked Nov 29 '19 11:11

Sole


Video Answer


2 Answers

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

like image 190
Adrita Sharma Avatar answered Nov 09 '22 20:11

Adrita Sharma


When you ask for a "correct" way, it is commonly recommended to avoid subscriptions in component when you don't have to. Prefer asyncpipe 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

like image 40
MoxxiManagarm Avatar answered Nov 09 '22 20:11

MoxxiManagarm