File

apps/live-weather/src/app/shared/smart-place-card/smart-place-card.component.ts

Implements

OnChanges

Metadata

selector weather-base-smart-place-card
styleUrls ./smart-place-card.component.scss
templateUrl ./smart-place-card.component.html

Index

Properties
Methods
Inputs
Outputs

Constructor

constructor(openWeatherService: OpenWeatherService, router: Router)

Creates instance of FavoritePlacesComponent class

Parameters :
Name Type Optional Description
openWeatherService OpenWeatherService No

instance to request weather details from open weather

router Router No

instance of angular router

Inputs

airQuality
Default value : false
place
Type : IPlace
placeImage
Default value : false

Outputs

addPlaceToFavorites
Type : EventEmitter<IPlace>

Methods

Public getWeatherReport
getWeatherReport(place: IPlace)

Gets weather condition for the requested location

Parameters :
Name Type Optional Description
place IPlace No

location details of the city

weather condition details observer

Public goToPlaceDetails
goToPlaceDetails(place: IPlace)

Navigate to details page of place requested

Parameters :
Name Type Optional Description
place IPlace No

to navigate

Returns : void
ngOnChanges
ngOnChanges(changes: SimpleChanges)
Parameters :
Name Type Optional
changes SimpleChanges No
Returns : void
Public toggleFavorite
toggleFavorite()

Toggles favorite state of a place

Returns : void

Properties

Public currentTime
Default value : new Date().toISOString()

Represents current time in ISO format

Public loadingWeather
Default value : false

Flag to check loading status of weather

weather
Type : IOpenWeatherReport | null
Default value : null
import { Component, Input, OnChanges, Output, SimpleChanges, EventEmitter } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs';

import { OpenWeatherService } from '../../core/open-weather/open-weather.service';
import { IOpenWeatherReport } from '../models/IOpenWeatherReport';
import { IPlace } from '../models/IPlace';

@Component({
  selector: 'weather-base-smart-place-card',
  templateUrl: './smart-place-card.component.html',
  styleUrls: ['./smart-place-card.component.scss'],
})
/**
 * Visualize place model as material card element
 */
export class SmartPlaceCardComponent implements OnChanges {
  @Input() place!: IPlace;

  @Input() airQuality = false;

  @Input() placeImage = false;

  weather: IOpenWeatherReport | null = null;

  /** Flag to check loading status of weather */
  public loadingWeather = false;

  /** Represents current time in ISO format */
  public currentTime = new Date().toISOString();

  @Output() addPlaceToFavorites: EventEmitter<IPlace> = new EventEmitter<IPlace>();

  /**
   * Creates instance of ``` FavoritePlacesComponent``` class
   *
   * @param openWeatherService instance to request weather details from open weather
   * @param router instance of angular router
   */
  constructor(private openWeatherService: OpenWeatherService, private router: Router) { }

  /**
   * Toggles favorite state of a place
   */
  public toggleFavorite(): void {
    if (!this.place) {
      return;
    }
    this.place.isFavorite = !this.place.isFavorite;
    this.addPlaceToFavorites.emit(this.place);
  }

  /**
   * Gets weather condition for the requested location
   *
   * @param place location details of the city
   * @returns weather condition details observer
   */
  public getWeatherReport(place: IPlace): Observable<IOpenWeatherReport> {
    return this.openWeatherService.getCurrentWeatherCondition(place);
  }

  /**
   * Navigate to details page of place requested
   *
   * @param place to navigate
   */
  public goToPlaceDetails(place: IPlace): void {
    this.router.navigate(['/city', place.name, place.id]);
  }

  /**
   * @internal
   */
  ngOnChanges(changes: SimpleChanges): void {
    if (changes.place && changes.place.currentValue) {
      this.loadingWeather = true;
      this.getWeatherReport(this.place).subscribe(
        (weather: IOpenWeatherReport) => {
          this.weather = weather;
          this.loadingWeather = false;
        },
        (_) => {
          this.weather = null;
          this.loadingWeather = false;
        }
      );
    }
  }
}
<div class="place-card mat-elevation-z11" fxLayout="column">
  <mat-toolbar
    fxLayout="row"
    fxLayoutAlign="space-around center"
    fxLayoutGap="0.5rem"
    class="place-card__header"
    color="primary"
  >
    <span id="place-name" (click)="goToPlaceDetails(place)" class="pointer">{{ place?.name }}</span>
    <span fxFlex></span>
    <mat-icon
      aria-hidden="false"
      [attr.aria-label]="'Mark  {{ place?.name }} as favorite'"
      class="pointer"
      [color]="place?.isFavorite ? 'accent' : ''"
      (click)="toggleFavorite()"
      >favorite</mat-icon
    >
  </mat-toolbar>
  <img
    mat-card-image
    *ngIf="place?.photoUrl && placeImage"
    [src]="place?.photoUrl"
    alt="A beautiful picture of {{ place?.name }}"
    class="place-card__image"
  />

  <weather-base-current-weather-summary-container
    [weather]="weather!.current"
    *ngIf="weather && weather.current"
  ></weather-base-current-weather-summary-container>
  <div *ngIf="!weather" fxLayout="column" fxLayoutGap="1rem" fxLayoutAlign="start center">
    <mat-progress-bar *ngIf="loadingWeather" mode="indeterminate" color="accent"></mat-progress-bar>
    <h3 *ngIf="loadingWeather">Loading weather details</h3>
    <h3 *ngIf="!loadingWeather">Not able to load weather details</h3>
  </div>

  <weather-base-current-weather-details-container
    fxFlex
    [weather]="weather!.current"
    *ngIf="weather && weather.current"
  >
  </weather-base-current-weather-details-container>
  <weather-base-air-pollution-card
    *ngIf="airQuality"
    fxFlex="30%"
    fxFlex.xs="100%"
    class="air-polution-details-container"
    [place]="place"
  ></weather-base-air-pollution-card>
</div>

./smart-place-card.component.scss

:host {
  width: 100%;
}

.place-card {
  .place-card__image {
    filter: brightness(80%);
    width: 100%;
    height: 230px;

    &:before {
      content: 'Image not available';
      display: block;
      position: absolute;
      height: 230px;
      background-size: contain;
      width: 100%;
      text-align: center;
      font-style: italic;
      color: #b38f8f;
      line-height: 230px;
      background-image: url(../../../assets/default-image.png);
    }
  }

  .pointer {
    cursor: pointer;
  }
}
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""