Blazor チュートリアル - PokeAPIを使ってみる

# はじめに

Blazorにて、以下のようなアプリケーションを作成します。
ポケモンの名前 or No.を入力してボタンを押すとカードが追加されます。

![PokeAPI.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/b9cdb7c6-bfeb-24bf-2a80-0802c17b3e3a.gif)

# PokeAPI

PokeAPIを使用する事でポケモンのデータを取得することが可能です。
ポケモンの名前、技、タイプなどなど...詳細は以下のページからどうぞ。

https://pokeapi.co/



# チュートリアル

Visual StudioでBlazorアプリを新規作成し、コードを追加していきます。


## 入力フォーム(テキストボックスとボタン)

入力テキストのバインド：`@bind="@pokemonName" `
ボタンを押した時の動作：`@onclick="GetPokemonImage"`

```HTML
<!-- ポケモン名入力フォーム -->
<div class="input-group mb-3">
    <input type="text" class="form-control" placeholder="Enter Pokemon Name / No" @bind="@pokemonName" />
    <div class="input-group-append">
        <button class="btn btn-primary" type="button" @onclick="GetPokemonImage">Get Image</button>
    </div>
</div>
```

## 取得したポケモンをカードスタイルで表示

取得済みのポケモンデータを展開する：`@foreach (var p in pokemonList)`

```HTML
<!-- 取得したポケモンのリストを表示 -->
<div class="row">
    @foreach (var p in pokemonList)
    {
        <div class="col-md-3 mb-3">
            <div class="card text-center" style="width: 100%;">
                <img src="@p.SpriteUrl" class="card-img-top" alt="@p.Name" />
                <div class="card-body">
                    <h5 class="card-title">[ @p.Id ] @p.Name</h5>
                </div>
            </div>
        </div>
    }
</div>
```

## データ構造の定義とAPI実行

```cs
@code {

    public class Pokemon
    {
        public string Name { get; set; }
        public string SpriteUrl { get; set; }
        public int Id { get; set; }
    }

    private List<Pokemon> pokemonList = new List<Pokemon>(); // ポケモンのリスト
    private string pokemonName = "pikachu"; // デフォルトのポケモン名
    private string loadingMessage = "Loading...";

    // ボタンクリック時の処理
    private async Task GetPokemonImage()
    {
        // PokeAPIのエンドポイント
        string apiUrl = $"https://pokeapi.co/api/v2/pokemon/{pokemonName.ToLower()}";

        // HttpClientを使用してデータを取得
        var httpClient = new HttpClient();
        var response = await httpClient.GetFromJsonAsync<Pokemon>(apiUrl);

        // 取得したデータをセット
        if (response != null)
        {
            // Pokemonの画像URLをセット
            response.SpriteUrl = $"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/{response.Id}.png";

            pokemonList.Add(response); // リストに追加
            loadingMessage = ""; // ローディングメッセージをクリア
        }
        else
        {
            loadingMessage = "Pokemon not found.";
        }
    }
}
```

# コード全体

~~~cs:Poke.razor

@page "/Poke"

<h3>PokeAPI</h3>

<!-- ポケモン名入力フォーム -->
<div class="input-group mb-3">
    <input type="text" class="form-control" placeholder="Enter Pokemon Name / No" @bind="@pokemonName" />
    <div class="input-group-append">
        <button class="btn btn-primary" type="button" @onclick="GetPokemonImage">Get Image</button>
    </div>
</div>

<!-- 取得したポケモンのリストを表示 -->
<div class="row">
    @foreach (var p in pokemonList)
    {
        <div class="col-md-3 mb-3">
            <div class="card text-center" style="width: 100%;">
                <img src="@p.SpriteUrl" class="card-img-top" alt="@p.Name" />
                <div class="card-body">
                    <h5 class="card-title">[ @p.Id ] @p.Name</h5>
                </div>
            </div>
        </div>
    }
</div>

@code {

    public class Pokemon
    {
        public string Name { get; set; }
        public string SpriteUrl { get; set; }
        public int Id { get; set; }
    }

    private List<Pokemon> pokemonList = new List<Pokemon>(); // ポケモンのリスト
    private string pokemonName = "pikachu"; // デフォルトのポケモン名
    private string loadingMessage = "Loading...";

    // ボタンクリック時の処理
    private async Task GetPokemonImage()
    {
        // PokeAPIのエンドポイント
        string apiUrl = $"https://pokeapi.co/api/v2/pokemon/{pokemonName.ToLower()}";

        // HttpClientを使用してデータを取得
        var httpClient = new HttpClient();
        var response = await httpClient.GetFromJsonAsync<Pokemon>(apiUrl);

        // 取得したデータをセット
        if (response != null)
        {
            // Pokemonの画像URLをセット
            response.SpriteUrl = $"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/{response.Id}.png";

            pokemonList.Add(response); // リストに追加
            loadingMessage = ""; // ローディングメッセージをクリア
        }
        else
        {
            loadingMessage = "Pokemon not found.";
        }
    }
}

~~~