Dinosaurs Component

Now it's time to call our API and display data to authenticated users in our Dinosaurs component.

Dinosaurs Component Class

Next open the dinosaurs.component.ts class file:

// src/app/pages/dinosaurs/dinosaurs.component.ts
import { Component, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { AuthService } from './../../auth/auth.service';
import { ApiService } from './../../data/api.service';
import { tap } from 'rxjs/operators';

@Component({
  selector: 'app-dinosaurs',
  templateUrl: './dinosaurs.component.html',
  styles: []
})
export class DinosaursComponent implements OnInit {
  loading = true;
  error: boolean;
  dinos$ = this.api.getDinos$().pipe(
    tap(
      res => this.loading = false,
      err => {
        this.loading = false;
        this.error = true;
      }
    )
  );
  pageTitle = 'Dinosaurs';

  constructor(
    private title: Title,
    public auth: AuthService,
    private api: ApiService
  ) { }

  ngOnInit() {
    this.title.setTitle(this.pageTitle);
  }

}

Dinosaurs Component Template

Next open the dinosaurs.component.html template file:

<!-- src/app/pages/dinosaurs/dinosaurs.component.html -->
<ng-template #noDinos>
  <app-loading *ngIf="loading"></app-loading>
  <app-error *ngIf="error"></app-error>
</ng-template>

<div *ngIf="(dinos$ | async) as dinos else noDinos">
  <h1 class="text-center py-2">🦕 {{ pageTitle }} 🦖</h1>
  <p *ngIf="!auth.isAuthenticated" class="text-center">
    Log in to learn more about dinosaurs!
  </p>
  <ng-container *ngFor="let dino of dinos">
    <app-dino [dino]="dino"></app-dino>
  </ng-container>
</div>

We're using the Async pipe declaratively in our template. This unwraps a value from our dinosaurs$ observable and will set up subscription and unsubscribing automatically. We'll also use the NgIf directive and a template reference variable to show the Loading component or Error component if dinosaurs$ | async has not emitted a value. The resulting value is set as dino, and we can then use the NgFor directive to iterate over the array of dinosaurs and display each one.

Note: You can test error handling in your app by stopping the Node API server. This will cause API requests to fail in the Angular app, and it should display errors appropriately.

Dino Details

We are also using the app-dino component to display additional details about the dinosaurs. Let's go ahead and implement that code as well.

Dinos Component

import { Component, OnInit, Input } from '@angular/core';
import { IDino } from '../../../data/dino.interface';
import { AuthService } from './../../../auth/auth.service';

@Component({
  selector: 'app-dino',
  templateUrl: './dino.component.html',
  styles: []
})
export class DinoComponent implements OnInit {
  @Input() dino: IDino;

  constructor(public auth: AuthService) { }

  ngOnInit() {
  }

}

Dino Template

<div class="card my-2">
  <div class="card-body">
    <h5 class="card-title">
      {{ dino.name }} <span *ngIf="dino.favorite">⭐️</span>
    </h5>
    <div class="card-text">
      <p class="mb-0">
        <em>({{ dino.pronunciation }})</em>
      </p>
      <a
        *ngIf="auth.isAuthenticated"
        class="btn btn-primary btn-sm mt-2"
        routerLink="/dinosaur/{{ dino.name | lowercase }}">Learn More</a>
    </div>
  </div>
</div>

results matching ""

    No results matching ""