Úkol API

3. Řešení úkolu

Třída CurrentWeather
using System.Text.Json.Serialization;

namespace API_Weather.Models
{
    public class CurrentWeather
    {
        [JsonPropertyName("temperature")]
        public double Temperature { get; set; }

        [JsonPropertyName("windspeed")]
        public double Windspeed { get; set; }

        [JsonPropertyName("time")]
        public string Time { get; set; }
    }
}

Třída CurrentWeather definuje datový model pro uchování informací o aktuálním počasí získaných ze vzdáleného API. Pro zajištění bezproblémové automatické deserializace dat z formátu JSON jsou vlastnosti třídy opatřeny atributem [JsonPropertyName]. Tento přístup umožňuje zachovat v C# kódu standardní jmenné konvence a zároveň přesně mapuje tyto vlastnosti na odpovídající textové klíče ve zdrojových datech ze serveru.


Třída WeatherResponse
using System.Text.Json.Serialization;

namespace API_Weather.Models
{
    public class WeatherResponse
    {
        [JsonPropertyName("current_weather")]
        public CurrentWeather CurrentWeather { get; set; }
    }
}

Třída WeatherResponse slouží jako hlavní obálka (kořenový objekt) pro data přijatá ze vzdáleného serveru. Aby bylo zajištěno automatické a bezchybné napojení na dříve vytvořený model vnořených dat o počasí, využívá se atribut [JsonPropertyName]. Ten umožňuje zachovat standardní pojmenování vlastnosti v C# (CurrentWeather s velkým písmenem) a spolehlivě ji propojit s odpovídajícím textovým klíčem "current_weather" ve struktuře JSONu.


Razor komponenta
@page "/"
@inject HttpClient Http

<PageTitle>Aktuální počasí</PageTitle>

<h1>Počasí v Praze</h1>

<p>Kliknutím na tlačítko zjistíš aktuální stav z Open-Meteo API.</p>

<button class="btn btn-primary mb-3" @onclick="ZiskatPocasi">Zjistit počasí</button>

@* Zobrazíme data pouze pokud už se stáhla *@
@if (aktualniPocasi != null)
{
    <div class="card" style="width: 18rem;">
        <div class="card-body">
            <h5 class="card-title">Teplota: @aktualniPocasi.Temperature °C</h5>
            <p class="card-text">Rychlost větru: @aktualniPocasi.Windspeed km/h</p>
            <p class="card-text text-muted"><small>Čas měření: @aktualniPocasi.Time</small></p>
        </div>
    </div>
}
@else if (nacteno == true)
{
    <p><em>Načítám data ze serveru...</em></p>
}

@code {
    private Models.CurrentWeather? aktualniPocasi;
    private bool nacteno = false;

    private async Task ZiskatPocasi()
    {
        nacteno = true;

        // Adresa s GPS souřadnicemi pro Prahu
        string url = "https://api.open-meteo.com/v1/forecast?latitude=50.088&longitude=14.4208&current_weather=true";

        // Zavoláme API a výsledek rovnou převedeme do našich C# tříd
        var vysledek = await Http.GetFromJsonAsync<Models.WeatherResponse>(url);

        if (vysledek != null)
        {
            aktualniPocasi = vysledek.CurrentWeather;
        }
    }
}

V části @code definujeme nullable proměnnou aktualniPocasi a logický stav nacteno. Kliknutím na tlačítko se přes událost @onclick spustí metoda ZiskatPocasi. Ta nejprve nastaví načítací stav a asynchronně (díky klíčovému slovu await prohlížeč nezamrzne) stáhne data z API, která rovnou převede na připravené objekty. V HTML části pak pomocí podmínek @if a else if dynamicky reagujeme na aktuální stav: dokud data putují po síti, zobrazuje se text o načítání, a jakmile se proměnná naplní (!= null), automaticky se vykreslí karta s aktuální teplotou a větrem.