Adding Angular Component and Service for the News API

According to the Angular documentation,  a service is a

 broad category encompassing any value, function, or feature that an app needs. A service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well.

In our case, we want to connect to our express API developed in the previous sessions and we set up this connection in our service and then inject it into our application whenever we need it. 

ng g service services/news

This will generate these two files under our services directory. 

 

In our news.service.ts file, we set up our connection to get the news items from our API in the getNewsByCategory function. 

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

export const NEWS_API_URL_ENDPOINT = 'http://localhost:3000/api/news/';

@Injectable({
  providedIn: 'root',
})
export class NewsService {
  constructor(private http: HttpClient) {}

  public getNewsByCategory(payload: string) {
    return this.http.get(NEWS_API_URL_ENDPOINT + payload);
  }
}

Since we want to make our angular application aware of the services we have to import the HttpClientModule into the main  app.module.ts as well and make it part of our imports. 

Add  HttpClientModule to imports in the main app module.

 

Next, we will generate a new component to load data from our news API

ng g component components/news-items

In this component, we will inject the news service and call the service when the angular component is initialized in the angular cycle ngOnInit.  In ngOnInit, we subscribe to our service which returns our news articles data. The component has an input called category which determines what category of news items to load.  It also has the property articles where we will store the articles retrieved for the component. 

import { Component, OnInit, Input } from '@angular/core';
import { NewsService } from '../../services/news.service';
import { NewsItem } from '../../models';

@Component({
  selector: 'app-news-items',
  templateUrl: './news-items.component.html',
  styleUrls: ['./news-items.component.css'],
  providers: [NewsService],
})
export class NewsItemsComponent implements OnInit {
  @Input() category: string = 'home';
  public articles: NewsItem[] = [];

  constructor(private newsService: NewsService) {}

  ngOnInit(): void {
    this.newsService
      .getNewsByCategory(this.category)
      .subscribe((data: NewsItem[]) => {
        this.articles = data;
      });
  }
}

 With the articles fetched and stored in articles, we can build our template to display these items. 

<div class="row">
  <div *ngFor="let article of articles" class="post col-xl-6">
    <div class="post-thumbnail">
      <a href="{{ article.url }}" class="animsition-link">
        <img src="{{ article.urlToImage }}" alt="..." class="img-fluid" />
      </a>
    </div>
    <div class="post-details">
      <div class="date meta-last">
        {{ article.publishedAt | date: "MM/dd/yy" }}
      </div>
    </div>
    <a href="{{ article.url }}" class="animsition-link">
      <h3 class="h4 w-100">{{ article.title }}</h3>
    </a>
    <p class="text-muted">{{ article.description }}</p>
    <footer class="post-footer d-flex align-items-center">
      <a href="#" class="author d-flex align-items-center flex-wrap">
        <div class="title">{{ article.author }}</div>
      </a>
    </footer>
  </div>
</div>

NOTE: In order to format the date of publication of an article in the template, we use angulars inbuilt pipes functionality as shown below. 

{{ article.publishedAt | date: "MM/dd/yy" }}

Further reading on pipes, how to use them, and how to build custom pipes can be found on the angular documentation site on pipes.