Adding Angular Component and Service for the Weather API

Next, we will generate a service to get data from the weather API built in the previous section. 

ng g service services/weather

This creates a new service and test file in the services sub-folder.  This service would be injected into the components and then load weather data. 

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

@Injectable()
export class WeatherService {
  constructor(private http: HttpClient) {}

  public getWeatherData(payload) {
    return this.http.get(WEATHER_API_URL_ENDPOINT + payload);
  }
}

Next, we will build a component to display the data retrieved from the API 

ng g component components/weather

The weather component is a bit more complex. We need to import FormControl from the

@angular/forms package. This will help us to build a small react form for searching weather data for different cities. In our component, we set some default properties, such as the city and its longitude and latitude points. 

 To have a bit more fun, we convert the temperature values retrieved from Fahrenheit to degree Celsius. 

import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';

import { debounceTime } from 'rxjs/operators';
import { distinctUntilChanged } from 'rxjs/operators';

import { WeatherService } from '../../services/weather.service';
import { Weather } from '../../models';

@Component({
  selector: 'app-weather',
  templateUrl: './weather.component.html',
  styleUrls: ['./weather.component.css'],
  providers: [WeatherService],
})
export class WeatherComponent implements OnInit {
  public name: string = 'Kumasi';
  public lat: number = 48.5768558;
  public lng: number = 13.268283;
  public temperature: number | string;
  public humidity: number = 50;
  public cityToSearch = new FormControl();

  constructor(private weatherService: WeatherService) {
    this.cityToSearch.setValue(this.name);
   
    this.cityToSearch.valueChanges
      .pipe(debounceTime(500), distinctUntilChanged())
      .subscribe((city) => {
        this.getWeatherData(city);
      });
  }

  private setMapParameters(data: Weather) {
    const { temp, humidity, name } = data;
    this.name = name;
    this.humidity = humidity;
    // T(°C) = (T(°F) - 32) × 5/9
    this.temperature = (((temp - 32) * 5) / 9).toFixed(2);
  }

  ngOnInit(): void {
    this.getWeatherData(this.cityToSearch.value);
  }

  public getWeatherData(city: string) {
    const currentCity = city || this.name;
    this.name = currentCity;
    this.weatherService
      .getWeatherData(currentCity)
      .subscribe((data: Weather) => {
        this.setMapParameters(data);
      });
  }
}

 

Building our display template. 

<div class="widget search">
  <header>
    <h3 class="h6">Search Weather</h3>
  </header>

  <form action="#" class="search-form" ngNoForm>
    <div class="form-group">
      <input
        type="search"
        name="cityToSearch"
        id="cityToSearch"
        [formControl]="cityToSearch"
        placeholder=" Search for City?"
      />
      <button type="submit" class="submit"></button>
    </div>
  </form>

  <div class="pt-5">
    <div class="h6">Currently displaying</div>
    <br />
    <div class="h6 alert alert-warning">City : {{ name }}</div>
    <br />
    <div class="h6 alert alert-success">Temperature : {{ temperature }}</div>
    <br />
    <div class="h6 alert alert-info">Humidity : {{ humidity }}</div>
  </div>
  <div class="pt-5"></div>
</div>