Angular: Weather Finder
Date
Author
Create a Weather Finder component, as shown below:
The component must have the following functionalities:
- The input should initially be empty. The user can type a city name into this input box to search for weather details for this city.
- Clicking on the ‘Search’ button should make an API GET call to the URL ‘https://jsonmock.hackerrank.com/api/weather?name=<name>’ using the Angular HttpClient module. Here, <name> is the city name entered into the text box. For example, for the value ‘Dallas’, the API request is https://jsonmock.hackerrank.com/api/weather?name=Dallas. There will be data for the cities ‘Dallas’ and ‘Oakland’.
- The response contains a data field, where data is an array of objects, and each object is a weather record. Only the first record of the array is rendered in this component. A sample data field for ‘Dallas’ is below:”data”: [ { “name”: “Dallas”, “weather”: “12 degree”, // Format is always “<value> degree” “status”: [ “Wind: 2Kmph”, // String “Humidity: 5%” // String ] } ]
- The weather details should be rendered inside <div data-test-id=”weather-details”></div> . This div should not be rendered initially since no API has been hit yet.
- Each weather record contains a weather field. Retrieve the value and display it in the <span data-test-id=”result-temperature”></span> element.
- If the value in the weather field is less than 20, render the cold weather icon by rendering <i data-test-id=”icon-cold”></i>. If the value is greater than or equal to 20, render the sunny weather icon by rendering <i data-test-id=”icon-sunny”></i>.
- Each weather record contains a status field which is an array of strings.
- The first string denotes the wind value and the second string denotes the humidity value.
- Render the wind value in <div data-test-id=”result-wind”></div>.
- Render the humidity value in <div data-test-id=”result-humidity”></div>.
- If no records are returned for any city, render <div data-test-id=”no-result”>No Results Found</div> instead. This element must be visible only when the data field is an empty array. This div should not be rendered initially since no API has been hit yet.
- Please note that the input field accepts only text. Test cases take will only call the API with valid input, so input validation is not required.
- For testing purposes, please use the following cities and their corresponding weather conditions:Dallas – Cold Oakland – Sunny
The following data-test-id attributes are required in the component for the tests to pass:
- The input: ‘app-input’
- The ‘Search’ button: ‘submit-button’
- The weather details: ‘weather-details’
- The sunny icon: ‘icon-sunny’
- The cold icon: ‘icon-cold’
- The span showing temperature: ‘result-temperature’
- The div showing wind information: ‘result-wind’
- The div showing wind information: ‘result-humidity’
- The ‘No Results Found’ div: ‘no-result’
Please note that the component has the listed data-test-id attributes for test cases and certain classes and ids for rendering purposes. They should not be changed.
SOLUTIONS:
//weatherFinder.component.ts
import {Component, OnInit, Input} from '@angular/core';
import { HttpClient } from "@angular/common/http";
interface CityWeather {
name: string;
weather: string;
status: string[];
}
interface ApiResponse {
page: number;
per_page: number;
total: number;
total_pages: number;
data: CityWeather[];
}
interface data{
name :String
temprature :String
wind :String
humidity :String
}
@Component({
selector: 'weather-finder',
templateUrl: './weatherFinder.component.html',
styleUrls: ['./weatherFinder.component.scss']
})
export class WeatherFinder implements OnInit {
constructor (private http :HttpClient){}
@Input() weatherData :data[];
city :any
cityDetails ={
data:[],
iconSunny :false ,
iconCold:false,
weather : null
}
showNoResult :boolean = false
hideDetails :boolean =false
cityChange(){
let value = this.city
if(value){
this.http.get('https://jsonmock.hackerrank.com/api/weather?name='+value).subscribe((res :any)=>{
this.cityDetails.data = res.data;
if(this.cityDetails.data.length == 0){
this.showNoResult = true
this.hideDetails = false
}else{
this.showNoResult = false
this.cityDetails.weather = res.data[0].weather
let t = res.data[0].weather;
let m = t.split(' ')
if(m[0] <20){
this.hideDetails =true
this.cityDetails.iconCold = true;
this.cityDetails.iconSunny = false;
}else if(m[0] >19 ){
this.hideDetails = true
this.cityDetails.iconSunny = true;
this.cityDetails.iconCold = false;
}
}
})
}
}
ngOnInit(): void {
}
}
//app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'Weather Finder';
}
/* weatherFinder.component.html */
wb_sunny
ac_unit
{{cityDetails.weather}}
{{cityDetails.data[0].status[0]}}
{{cityDetails.data[0].status[1]}}
No Results Found