Meteo (apixu) service.
Net zoals bij de todo-app ga je alle functionaliteiten omtrent de meteo API groeperen in één service. De taak van de service is om de HTTP-aanvraag in te dienen en het antwoord van de weersgegevens terug te sturen naar de component(en) die de aanvraag deden.
Voor je de service kan uitwerken, heb je natuurlijk wel een API nodig die onze verzoeken kan verwerken. Voor deze toepassing gebruiken we de Apixu API. Deze dienst is tot 5000 API calls per maand volledig gratis. Het enige wat je nodig hebt, is een API-key.
- Maak een account aan op https://www.apixu.com/.
- Genereer een API-key.
- Bestudeer de documentatie van Request API en de JSON-data die we terugkrijgen.
Aan de hand van een aantal parameters kunnen we het resultaat beïnvloeden. De parameters die ons interesseren zijn:
- key: uw API-key.
- q: de locatie waarover we informatie wensen te ontvangen. Deze string kan zowel een woord (q=Geel) als een combinatie van lat,lng coördinaten bevatten (q='51.160854,4.961262').
- days: het aantal dagen (minimaal 1 en maximaal 10) waarvoor je de weersvoorspelling terugkrijgt.
- lang: de taal waarin de omschrijving wordt weergegeven.
Ziehier de weersvoorspelling van Geel. Vervang in de URL eerst de key (SECRET) door je eigen API-key!
https://api.apixu.com/v1/forecast.json?key=SECRET&q=Geel_belgium&days=7&lang=nl
TIP: voeg de Chrome-extensie JSON Formatter
toe zodat je het resultaat mooi gestructureerd kan bekijken.
De velden die je dadelijk in de site verwerkt, zijn:
- location.name en location.country: onze locatie.
- current.temp_c, current.condition.text en current.condition.icon: de weersvoorspelling op dit moment.
- forecast.forecastday: een array van objecten met onder andere de dag (date_epoch), de temperatuur (day.mintemp_c en day.maxtemp_c), de Nederlandse omschrijving (day.condition.text) en het icoon (day.condition.icon).
HttpClientModule
Om de data in de achtergrond op te halen, maken je via de HttpClient een AJAX request naar de apixu
API. Voor je de HttpClient kan gebruiken, moet je de HttpClientModule eerst importeren. Omdat we
deze module verder in de toepassing nog gebruiken, importeren we deze best in app.module.ts.
Eens de HttpClientModule geïmporteerd, kan je de HttpClient, via de constructor, in al je
componenten en
services injecteren.
- Importeer HttpClientModule in app.module.ts:
Service aanmaken.
- Maak in de map services de apixu-service aan.
$ ng g s services/apixu - Wijzig de code op src/app/services/apixu.service.ts:
- Lijn (1):
Importeer HttpClient en HttpParams. - Lijn (2):
Injecteer de HttpClient in de constructor. Verder in de code kan je service gebruiken via this.http. - Lijn (3):
Vul hier je eigen API-key in. - Lijn (4):
De methode getForecast$(location) geeft ons een observable terug. Let op: de code binnen een observable wordt pas uitgevoerd zodra je op de observable subscribed! - Lijn (5):
Uit ons voorbeeld weten we dat je aan de URL nog enkele paramaters moet toevoegen. Je kan dus perfect de volledige URL, inclusief de paramaters, in de get methode plaatsen. Om de code wat leesbaarder te maken, kan je ook opteren om alle paramaters in een variabele (params) te plaatsen en deze als tweede argument aan de get methode mee te geven. - Lijn (6):
Met de operator tap(), kan je tijdens de stream makkelijk tussentijdse waardes opvragen zonder de stram zelf te beïnvloeden. Dit is vooral interessant om de stream te debuggen. - Lijn (7):
Stel dat er iets mis loopt, dan wil je dit natuurlijk ook onderscheppen. Dit doe je binnen de catchError operator van rxjs.
Een foutmelding bevat heel wat informatie. Best dat je de foutmelding eerst in de console logt. Dan zal je merken dat error.message de foutomschrijving bevat. Best dat je bij een fout toch een waarde (EMPTY) teruggeeft aan de observable zodat de code niet "hangt". - Lijn (8):
Zodadelijk gaan we in de rootmodule meermaals op getForecast() subscriben. Voor Angular betekent dit dat we meermaals de data opnieuw gaan ophalen! Dit is natuurlijk voor niets nodig. De data is immers altijd hetzelfde.
Om deze overbodige connecties te beperken tot één connectie (hot observable), eindig je de request met de ingebouwde rxjs-operator shareReplay(). Vergeet niet alle rxjs-operators te importeren.