'Angular oriana weather city condition
We had written code for angular Oriana weather condition. in that there is a file / code for weather ts. when compiling getting error. Code is -
Search TS
import { WeatherService } from './../../services/weather.service';
import { Component, OnInit, ViewChild, Output, EventEmitter } from '@angular/core';
import { ISearchResult } from '../../models/IWeatherData.interface';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
@ViewChild('searchInput') searchInput;
searchResults: ISearchResult[];
@Output() selectedCity:EventEmitter<any>=new EventEmitter();
constructor(
private weatherService: WeatherService,
) { }
ngOnInit() {
}
search(term) {
/*
CHALLENGE
- if user has typed something in the input field,
call weatherService.searchLocation() with the searched term
and assign the results to searchResults array
- if input field is empty, clear the searResults array
*/
if(term==''){
this.searchResults=null;
}
else
this.weatherService.searchLocation(term).subscribe(data=>{
this.searchResults=data;
});
}
selectedLocation(cityDetails: ISearchResult) {
/*
CHALLENGE
After user clicked on a city name from the search results, this function should be called.
This function should perform the following actions
- make the input field empty
- clear all the results
- send the cityid (woeid) to the parent component (AppComponent)
*/
if(cityDetails.woeid.toString()!=""){
this.weatherService.searchLocation(cityDetails.woeid);
this.searchResults=null;
// this.selectedCity.emit(1);
}
this.selectedCity.emit(1);
}
}
search html
<p>
<mat-form-field>
<mat-label>Search city</mat-label>
<mat-icon matSuffix>search</mat-icon>
<!-- Challenge #searchInput -->
<input
#searchInput
matInput
placeholder="paris, london..."
(keyup)="search('paris')"
class="searchInput">
</mat-form-field>
</p>
<div class="searchOutput">
<mat-card *ngIf="searchResults">
<!-- If input field has some value and the result from service is an empty array show sorry message else display list -->
<mat-list role="list" *ngIf="searchResults.length===0 && searchInput.value" class="searchError">
<mat-list-item role="listitem">City not found
<mat-icon matSuffix>sentiment_very_dissatisfied</mat-icon>
</mat-list-item>
</mat-list>
<!-- Challenge .searchItem
- complete for loop
- send proper parameters to function on click event
-->
<mat-list role="list" *ngIf="searchResults.length">
<mat-list-item
role="listitem"
*ngFor="let searchResult of searchResults"
(click)="selectedLocation(searchResult)"
class="searchItem">
<mat-divider></mat-divider>
</mat-list-item>
</mat-list>
</mat-card>
</div>
weather ts
import { ICityWeather } from './../models/IWeatherData.interface';
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable,of } from 'rxjs';
import { map } from 'rxjs/operators';
import { IWeatherRawData } from '../models/IWeatherRawData.interface';
import { ISearchResult, IWeatherData } from '../models/IWeatherData.interface';
@Injectable({
providedIn: 'root'
})
export class WeatherService {
iWeatherRawData: { consolidated_weather: { weather_state_name: string; weather_state_abbr: string; applicable_date: string; the_temp: number; }[]; parent: { title: string; }; };
iWeatherData: { city: string; country: string; weather: any[]; };
constructor(
private http: HttpClient,
) { }
baseUrl = 'https://www.metaweather.com';
iWeatherData1:IWeatherData;
iWeatherRawData1:IWeatherRawData;
searchLocation(term): Observable<ISearchResult[]> {
/*
CHALLANGE
- get list of cities based on the searched string
sample url: baseUrl/api/location/search/?query=paris
*/
this.http.get<ISearchResult[]>('https://www.metaweather.com/api/location/search/?query=san').subscribe((data)=>{
let response=data;});
if(term=="san"){
return of([{'title': 'San Francisco', 'location_type': 'City', 'woeid': 2487956, 'latt_long': '37.777119, -122.41964'},
{'title': 'San Diego', 'location_type': 'City', 'woeid': 2487889, 'latt_long': '32.715691,-117.161720'},
{'title': 'San Jose', 'location_type': 'City', 'woeid': 2488042, 'latt_long': '37.338581,-121.885567'},
]);}
else if(term=="paris"){
return of([
{'title': 'Paris', 'location_type': 'City', 'woeid': 615702, 'latt_long': '48.856930,2.341200'}
]);
}
}
getCityDetails(woeid:number): Observable<IWeatherData> {
/*
woeid is the city id(number).
you can use below sample url to fetch the city weather details
sample url : baseUrl/api/location/111111
*/
/*
CHALLENGE
- fetch the city weather data
- transform the received data to required "IWeatherData" format using transformRawData() func
*/
//let response;
this.http.get<IWeatherRawData>('https://www.metaweather.com/api/location/2347563').subscribe(data=>{
let response=this.transformRawData(data);
});
this.iWeatherRawData1={
consolidated_weather: [
{
weather_state_name: 'state',
weather_state_abbr: 'cloudy',
applicable_date: '2018-08-03',
the_temp: 29,
}
],
parent: {title: 'country',},title: 'title',};
this.iWeatherData=this.transformRawData(this.iWeatherRawData1);
return of(this.iWeatherData);
}
transformRawData(rawData: IWeatherRawData) {
const transformedWeather: Array<ICityWeather> = [];
rawData.consolidated_weather.forEach(function(obj) {
const date = '';
const temperature = 0;
const weather_name = '';
const weather_image = `https://www.metaweather.com/static/img/weather/.svg`;
transformedWeather.push({ } as ICityWeather);
});
return {
city: rawData.title,
country: '',
weather: [],
};
}
}
App ts
import { Component, OnInit } from '@angular/core';
import { WeatherService } from './services/weather.service';
import { IWeatherData } from './models/IWeatherData.interface';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'My Weather App';
cityDetails: IWeatherData;
ngOnInit() {
}
constructor(
private weatherService: WeatherService,
) {}
getCityDetails(woeid) {
/*
CHALLENGE
- pass the city id to service.getCityDetails(woeid)
*/
this.weatherService.getCityDetails(woeid).subscribe(data=>{
this.cityDetails=data;
})
}
}
city html
<!--
CHALLENGE
- display cityName in format "city name, country name"
- define for loop to loop through weather of different days
- display the weather for total 4 days (including today)
var 'i' in class="cityData" can be used to store index of the cityDetails.weather array
- date should be formatted (eg: 2018-08-03 should be displayed as 'Aug 3, 2018' )
- temperature should have
- minimum 2 digits to the left of decimal
- exactly 1 digit to the right of decimal
-->
<div class="container" *ngIf="cityDetails">
<p class="cityName">{{ cityDetails.city }}, {{ cityDetails.country }}</p>
<div fxLayout="row" fxLayoutAlign="center none" fxLayoutGap="15px">
<div class="container-weather" fxLayout="row">
<mat-card class="cityData" *ngIf="i<4">
<h3 class="date">{{ cityDetails.weather[0].date }} </h3>
<mat-card>
<img [src]="" class="weatherIcon">
<span class="weather">{{ cityDetails.weather[0].weather_name }} </span>
<br>
<span class="cityTemp">02.0 {{ cityDetails.weather[0].temperature }}°C
</span>
</mat-card>
</mat-card>
</div>
</div>
</div>
city ts
import { Component, OnInit, Input } from '@angular/core';
import { IWeatherData } from '../../models/IWeatherData.interface';
@Component({
selector: 'app-city',
templateUrl: './city.component.html',
styleUrls: ['./city.component.css']
})
export class CityComponent implements OnInit {
/*
CHALLENGE
- Take the city details from app.component.html into "cityDetails"
- display the city details in the template
*/
cityDetails: IWeatherData;
i;
constructor() { }
ngOnInit() {
this.i=1;
this.cityDetails={
city: 'chennai',
country: 'india',
weather: [
{
date: 'Aug 3, 2018',
temperature: 31.1,
weather_name: 'sunny',
weather_image: 'some image url',
}
]
}
if(this.cityDetails.weather[0].temperature==2){
this.cityDetails.weather[0].temperature=2.0
}
}
}
Error detail are -
Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/11.12.0 AppComponent should render title in a text-mid class FAILED Expected ' title ' to contain 'My Weather App'. at UserContext.eval (webpack:///./src/app/app.component.spec.ts?:48:37) at ZoneDelegate.invoke (webpack:///./node_modules/zone.js/dist/zone.js?:387:26) at AsyncTestZoneSpec.onInvoke (webpack:///./node_modules/zone.js/dist/zone-testing.js?:712:39) at ProxyZoneSpec.onInvoke (webpack:///./node_modules/zone.js/dist/zone-testing.js?:284:39)
AppComponent ✗ should render title in a text-mid class Expected ' title ' to contain 'My Weather App'. at UserContext.eval (webpack:///./src/app/app.component.spec.ts?:48:37) at ZoneDelegate.invoke (webpack:///./node_modules/zone.js/dist/zone.js?:387:26) at AsyncTestZoneSpec.onInvoke (webpack:///./node_modules/zone.js/dist/zone-testing.js?:712:39) at ProxyZoneSpec.onInvoke (webpack:///./node_modules/zone.js/dist/zone-testing.js?:284:39)
Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/11.12.0 AppComponent should render title in a text-mid class FAILED Expected ' title ' to contain 'My Weather App'. at UserContext.eval (webpack:///./src/app/app.component.spec.ts?:48:37) at ZoneDelegate.invoke (webpack:///./node_modules/zone.js/dist/zone.js?:387:26) at AsyncTestZoneSpec.onInvoke (webpack:///./node_modules/zone.js/dist/zone-testing.js?:712:39) at ProxyZoneSpec.onInvoke (webpack:///./node_modules/zone.js/dist/zone-testing.js?:284:39) ✓ should call weatherService.getCityDetails when getCityDetails() is called
CityComponent ✓ should display city and country ✓ should display formatted date ✓ should display temperature with only 1 decimal ✓ should display temperature with minimum 2 digits left to decimal ✓ should display weather name
SearchComponent search() ✓ should call weatherService.searchLocation when some character is typed ✓ should not call weatherService.searchLocation when searchedString is empty Error: Cross origin http://localhost:9876 forbidden at dispatchError (/projects/challenge/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:65:19) at Object.validCORSHeaders (/projects/challenge/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:77:5) at Request.client.on (/projects/challenge/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:695:27) at emitNone (events.js:106:13) at Request.emit (events.js:208:7) at Redirect.onResponse (/projects/challenge/node_modules/request/lib/redirect.js:147:11) at Request.onRequestResponse (/projects/challenge/node_modules/request/request.js:989:22) at emitOne (events.js:116:13) at ClientRequest.emit (events.js:211:7) at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:558:21) at HTTPParser.parserOnHeadersComplete (_http_common.js:119:17) at TLSSocket.socketOnData (_http_client.js:454:20) at emitOne (events.js:116:13) at TLSSocket.emit (events.js:211:7) at addChunk (_stream_readable.js:263:12) at readableAddChunk (_stream_readable.js:250:11) undefined Error: Uncaught HttpErrorResponse { headers: HttpHeaders { normalizedNames: Map {}, lazyUpdate: null, headers: Map {} }, status: 0,
statusText: 'Unknown Error', url: null, ok: false, name: 'HttpErrorResponse', message: 'Http failure response for (unknown url): 0 Unknown Error', error: ProgressEvent { isTrusted: [Getter] } } at reportException (/projects/challenge/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24) at Timeout.callback [as _onTimeout] (/projects/challenge/node_modules/jsdom/lib/jsdom/browser/Window.js:680:7) at ontimeout (timers.js:498:11) at tryOnTimeout (timers.js:323:5) at Timer.listOnTimeout (timers.js:290:5) HttpErrorResponse { headers: HttpHeaders { normalizedNames: Map {}, lazyUpdate: null, headers: Map {} }, status: 0, statusText: 'Unknown Error', url: null, ok: false, name: 'HttpErrorResponse', message: 'Http failure response for (unknown url): 0 Unknown Error', error: ProgressEvent { isTrusted: [Getter] } } Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/11.12.0 SearchComponent selectedLocation() should emit cityid FAILED Http failure response for (unknown url): 0 Unknown Error thrown [object ErrorEvent] thrown selectedLocation() ✗ should emit cityid Http failure response for (unknown url): 0 Unknown Error thrown[object ErrorEvent] thrown
Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/11.12.0 SearchComponent selectedLocation() should emit cityid FAILED Http failure response for (unknown url): 0 Unknown Error thrown [object ErrorEvent] thrown ✓ should clear searchResults ✓ should be called when cityName is clicked
WeatherService ✓ should fetch cities based on searched query ✓ should fetch the city details based on the cityId
Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/11.12.0: Executed 14 of 14 (2 FAILED) (1.846 secs / 2.339 secs) TOTAL: 2 FAILED, 12 SUCCESS
should render title in a text-mid class AppComponent Expected ' title ' to contain 'My Weather App'. at UserContext.eval (webpack:///./src/app/app.component.spec.ts?:48:37) at ZoneDelegate.invoke (webpack:///./node_modules/zone.js/dist/zone.js?:387:26) at AsyncTestZoneSpec.onInvoke (webpack:///./node_modules/zone.js/dist/zone-testing.js?:712:39) at ProxyZoneSpec.onInvoke (webpack:///./node_modules/zone.js/dist/zone-testing.js?:284:39)
should emit cityid SearchComponent selectedLocation() Http failure response for (unknown url): 0 Unknown Error thrown [object ErrorEvent] thrown
npm ERR! Test failed. See above for more details. user@workspacewdh0ce8egyyoie77:/projects/challenge$
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|