Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Create a Pokedex app with Blazor and C#
Oscar Montenegro
Oscar Montenegro

Posted on • Edited on • Originally published atunitcoding.com

     

Create a Pokedex app with Blazor and C#

This is a repost from my origin article published on my blog:Unit Coding go and check it out! ✨

Creating web applications that consume rest api's are a great starting point to get better at any programming language at the same time that you are building something that is both useful and fun.

Today we will build the famous pokemon "pokedex" using c# as our programming language and Blazor as the web framework and we will be using .net 7 for this project you can use any other version that you want bus some things on the project structure and some declarations will change, so having said this let's beding coding!

Create the application

Create new empty blazor wasm projectdotnet new blazorwasm-empty -o BlazorDex (You can use the default version of blazor wasm you will only have to deal with the boilerplate code that microsoft provides on any new project).

We will be using the Pokemon API at PokéAPI (pokeapi.co) on the home page there is a "Try it now" section that allows you to try the api to figure out how it works. One simple example is calling the urlhttps://pokeapi.co/api/v2/pokemon/pikachu and you will get a huge json response that contains the data from "Pikachu".

Pokemon api page

From there we need to convert the json response that we get from the api when we search for a pokemon to C# classes so we can use them on our application. For you can go to a web page like Convert JSON to C# Classes Online - Json2CSharp Toolkit or you can use plugins that parse the json to classes on pasting or if you are using visual studio there is a built in tool to paste any json as C# classes so feel free to use any of this.

Json to csharp page

Create the pokemon models

From the conversion from json to C# classes we need the "root" class which we will rename to "pokemon" and remove some properties that we will not use, also we need classes like type, stats and sprites. So you should have theese c# classes in a folder called Models in the root of your project.

publicclassPokemon{publicintid{get;set;}=0;publicstringname{get;set;}="";publicintweight{get;set;}=0;publicintheight{get;set;}=0;publicSpritessprites{get;set;}=newSprites();publicList<Stat>stats{get;set;}=newList<Stat>();publicList<Type>types{get;set;}=newList<Type>();}publicclassSprites{publicstringback_default{get;set;}publicobjectback_female{get;set;}publicstringback_shiny{get;set;}publicobjectback_shiny_female{get;set;}publicstringfront_default{get;set;}publicobjectfront_female{get;set;}publicstringfront_shiny{get;set;}publicobjectfront_shiny_female{get;set;}}publicclassStat{publicintbase_stat{get;set;}publicinteffort{get;set;}publicStat2stat{get;set;}}publicclassStat2{publicstringname{get;set;}publicstringurl{get;set;}}publicclassType{publicintslot{get;set;}publicType2type{get;set;}}publicclassType2{publicstringname{get;set;}publicstringurl{get;set;}}
Enter fullscreen modeExit fullscreen mode

Create the Http client to fetch the pokemon data from the api

Now create a new folder called Util as short for utilites in the root of our project and create the http client called PokeClient with the following code.

usingSystem.Text.Json;usingBlazorDex.Models;namespaceBlazorDex.Properties{publicclassPokeClient{privateHttpClientClient{get;}publicPokeClient(HttpClientclient){this.Client=client;}publicasyncTask<Pokemon>GetPokemon(stringid){varresponse=awaitthis.Client.GetAsync($"<https://pokeapi.co/api/v2/pokemon/{id}/>");varcontent=awaitresponse.Content.ReadAsStringAsync();returnJsonSerializer.Deserialize<Pokemon>(content);}}}
Enter fullscreen modeExit fullscreen mode

Now go to Program.cs and add the following line above the builder.build.RunAsync() line.

builder.Services.AddScoped<PokeClient>();
Enter fullscreen modeExit fullscreen mode

Create a new page to display all the pokemons
Now inside the Pages folder create a new page called Index or use the one that is already there and add the code below.

@page"/"@usingModels@usingProperties@injectPokeClientclient@code{Pokemonpokemon=newPokemon();protectedoverrideasyncTaskOnInitializedAsync(){pokemon=awaitclient.GetPokemon("1");Console.WriteLine(pokemon.name);}}
Enter fullscreen modeExit fullscreen mode

If you run the project and go into the console you should be able to see the pokemon name displayed there.

Add bootstrap

For styling we will be using a mixture of some bootstrap classes and our custom css, but before using bootstrap we must install it. Open the console inside visual studio and run the following commands to initialize libman and install bootstrap.

libman initlibman install twitter-bootstrap@5.2.3
Enter fullscreen modeExit fullscreen mode

Then you will be prompted to select the folder destination, if you select the default destination you should have something like the following.
bootstrap directory location

Now go into index.html file and insert the cdn link tag to bootstrap and another css link tag to our project, this should have the name of your project, mine is Blazordex.

<linkhref="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css"rel="stylesheet"integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD"crossorigin="anonymous"><linkhref="css/app.css"rel="stylesheet"/><linkrel="stylesheet"href="BlazorDex.styles.css">
Enter fullscreen modeExit fullscreen mode

Add initial html markup to Index.razor and create PokemonList property

Add the initial markup on the Index page
Now that we have bootstrap working and our styles tags are in place let's begin adding some initial markup and some code.

<divclass="container"><divclass="pokemon-row">@foreach(varpinpokemonList){<divclass="pokemon-card"><imgsrc="@p.sprites.front_default"alt=""><h4class="pokemon-name">@p.name</h4><divclass="type-row">@foreach(vartypeinp.types){<span>@type.type.name</span>}</div></div>}</div></div>@code{List<Pokemon>pokemonList=newList<Pokemon>();protectedoverrideasyncTaskOnInitializedAsync(){for(inti=1;i<152;i++){pokemonList.Add(awaitclient.GetPokemon(i.ToString()));StateHasChanged();}}}
Enter fullscreen modeExit fullscreen mode

Now you should be able to see some pokemons getting displayed on the index page, this is not styled yet, we will implement those classes right now.

Add initial css

*{box-sizing:border-box;}.container{margin-top:50px;display:flex;flex-direction:column;}.pokemon-row{display:flex;flex-direction:row;flex-wrap:wrap;gap:50px;justify-content:center;align-items:center;}.pokemon-card{width:200px;height:250px;padding:10px;background-color:#FFF;align-items:center;text-align:center;border-radius:10px;box-shadow:010px10pxrgba(0,0,0,0.15);}img{width:80%;height:60%;}.type-row{display:flex;justify-content:space-around;}.pokemon-name{text-transform:capitalize;text-decoration:none;color:#000;}
Enter fullscreen modeExit fullscreen mode

Add another utilities class to display the color of the Pokémon type badge

To display the color of the types such as "water, fire, greass, etc" we will create a new utilite class called "PokeColor" and therefore call this on the Index page.

namespacenewBlazorDex.Util{publicstaticclassPokeColor{publicstaticstringGetTypeColor(stringtype){stringcolor=typeswitch{"bug"=>"#26de81","dragon"=>"#ffeaa7","electric"=>"#fed330","fairy"=>"#FF0069","fighting"=>"#30336b","fire"=>"#f0932b","flying"=>"#81ecec","grass"=>"#00b894","ground"=>"#EFB549","ghost"=>"#a55eea","ice"=>"#74b9ff","normal"=>"#95afc0","poison"=>"#6c5ce7","psychic"=>"#a29bfe","rock"=>"#2d3436","water"=>"#0190FF",_=>"#0190FF"};returncolor;}}}
Enter fullscreen modeExit fullscreen mode

Add styling for span for type badge

Now let's call this utilitie class inside our Index page, on the Span elements that contains the class badge-type. Also below is the code to style this badge.

<spanclass="badge-type"style="background-color: @PokeColor.GetTypeColor(@type.type.name);">@type.type.name</span>
Enter fullscreen modeExit fullscreen mode
.type-badge {    padding: 5px;    padding-left: 10px;    padding-right: 10px;    border-radius: 8px;    font-size: 13px;    color: #fff;    text-transform: uppercase;    margin-right: 3px;}
Enter fullscreen modeExit fullscreen mode

Add a title with Pokémon like font.

For this kind of font I wen to to a page like text craft and generated an image for our application with pokemon like font styling. After having this put this image inside the img directory and add the image tag inside the Index page.

Application title image

<divclass="container"><imgsrc="/img/Blazor-Dex.png"class="app-title"> //Add this line<divclass="pokemon-row">
Enter fullscreen modeExit fullscreen mode
.app-title {    width: 400px;    margin: 0 auto 20px auto;}
Enter fullscreen modeExit fullscreen mode

Create PokemonCard Page and add initial code to make it work and display a pokemon

Now let's create a new page to display a single pokemon and show relevant data about like stats and wegith and height.

@page"/pokemon"@injectnewBlazorDex.Util.PokeClientclient<h1>PokemonCard</h1><h2>@poke.name</h2><imgsrc="@poke.sprites.front_default"alt="">@code{Pokemonpoke=newPokemon();protectedasyncoverrideTaskOnInitializedAsync(){poke=awaitclient.GetPokemon("1");}}
Enter fullscreen modeExit fullscreen mode

Add a new function in PokeColor class to Get Stats color

Now add a new function in the class PokeColor to get the color from the stats, as the past function to get the color from the type this will return the color hex code for the color of the stat we are currenty displaying.

publicstaticstringGetStatColor(stringstat){stringcolor=statswitch{"hp"=>"#FE0000","attack"=>"#EE7F30","defense"=>"#F7D02C","special-attack"=>"#F85687","special-defense"=>"#77C755","speed"=>"#678FEE",_=>"#0190FF"};returncolor;}
Enter fullscreen modeExit fullscreen mode

Add the rest of the code to PokemonCard page

Now add the resto of the markup, here we are doing many things. We are adding calls to GetTypeColor function and GetStatColor function, also we are passing a Parameter for this page called PokemonId to know which pokemon we should be displaying. Aside from calls to another PokeUtil class which will randomly display a type of pokeball to the left of the pokemon name.

@page"/pokemon/{pokemonId}"@usingModels@usingProperties@usingUtil@injectPokeClientclient<divclass="container"><divclass="card">@if(@poke.types.Count>0){<divclass="card-top"><imgsrc="@poke?.sprites?.front_default"alt="pokemon sprite"class="card-img-top"></div>}<divclass="inner-container"><divclass="stats-head"><divclass="icon-container"><imgsrc="/img/@PokeUtil.GetRandomBall()"class="poke-icon"/>"<h1class="pokemon-namecard-title"><b>@poke?.name</b></h1></div><divclass="pokemon-info"><h5>Height:@GetPokemonHeightInMeters(poke.height)m</h5><div>@foreach(vartypeinpoke.types){<spanclass="type-badge"style="background-color: @ShowTypeColor(@type.type.name);">@type.type.name</span>}</div><h5>Weight:@GetPokemonWeightInKilograms(poke.weight)kg</h5></div></div><divclass="stats-head"><divclass="icon-container"><imgsrc="<https://img.icons8.com/color/48/null/insignia-3.png>"class="poke-icon"/><h2>Stats</h2></div>@foreach(varstatinpoke?.stats){<divclass="stat-bar"><h5class="stat">@stat.stat.name: @stat.base_stat</h5><divclass="progress"><divclass="progress-barprogress-bar-striped" role="progressbar"style="width: @stat.base_stat%; background-color: @GetStatColor(@stat.stat.name);"aria-valuenow="100"aria-valuemin="0"aria-valuemax="200"></div></div></div>}</div></div></div></div>@code{[Parameter]publicstringpokemonId{get;set;}="";Pokemonpoke=newPokemon();protectedoverrideasyncTaskOnInitializedAsync(){poke=awaitclient.GetPokemon(pokemonId);}}
Enter fullscreen modeExit fullscreen mode

Add the styling for PokemonCard

.pokemon-name{text-transform:capitalize;}img{width:200px;}.badge{text-transform:capitalize;}.container{margin:30pxauto;width:28%;}.inner-container{margin:0auto;width:100%;text-align:center;padding:20px;padding-top:0px;}.card-top{display:flex;flex-direction:column;text-align:center;align-items:center;border-radius:15px;}.card{box-shadow:020px30pxrgba(0,0,0,0.3);border-radius:15px;}.pokemon-info{display:flex;justify-content:space-around;align-items:center;margin-bottom:10px;}.type-badge{padding:5px;padding-left:10px;padding-right:10px;border-radius:8px;font-size:13px;color:#fff;text-transform:uppercase;margin-right:3px;}.stat{text-transform:capitalize;}.stat-bar{display:flex;flex-direction:column;text-align:left;margin-bottom:5px;}.stats-head{background-color:#F0F0F0;padding:10px;border-radius:15px;margin-top:5px;}.poke-icon{width:30px;height:30px;margin-right:10px;}.icon-container{display:flex;align-items:center;justify-content:center;}
Enter fullscreen modeExit fullscreen mode

Create another util class called PokeUtil to manage measurement units and convert them along with a function to get a random pokeball

Units in the pokeapi are not pounds or kilograms for weight types, the same for height so this class is to convert those measurement units to kilograms and meters and the GetRandomBall function will return a random pokeball to display to simulate that we catched this pokemon with that pokeball.

usingSystem.Globalization;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Threading.Tasks;namespaceBlazorDex.Util{publicstaticclassPokeUtil{publicconststringPokeball="icons8-pokeball-96.png";publicconststringGreatBall="icons8-superball-96.png";publicconststringUltraBall="icons8-ultra-ball-96.png";publicconststringMasterBall="icons8-mega-ball-96.png";publicstaticstringGetRandomBall(){varpokeballArray=newstring[]{Pokeball,GreatBall,UltraBall,MasterBall};varrand=newRandom();stringrandomBall=pokeballArray[rand.Next(pokeballArray.Length)];returnrandomBall;}publicstaticdoubleGetPokemonHeightInMeters(intheight){returnConvert.ToDouble(height)/10;}publicstaticdoubleGetPokemonWeightInKilograms(intweight){returnConvert.ToDouble(weight)/10;}}}
Enter fullscreen modeExit fullscreen mode

Thanks, and consider supporting me! 🙌🏽

This is it, now you have a complete pokedex with C# and blazor that load pokemons dynamically without the need to use any javascript which is awesome.

This is my first article on dev.to so I know there will be some or lots of errors so big apologies 🙇🏽‍♂️, anyways the code will be available on my kofi page and there ir also a youtube version where you can code along with me.

If you enjoyed this guide please follow me on my journey to create cool and fun projects for C# and the .NET community because I consider we need more projects like that that can engage people with topics that we like and that are catchy for the eye 👁️.

https://www.youtube.com/@unitcoding6783

Also if you really enjoyed the project please consider supporting me on kofi I would be really grateful as that would help me to continue creating more of this cool content.

Kofi support image

https://ko-fi.com/unitcoding

Also other ways to support me would be to continue my next articles on dev.to and following me on youtube!

Thanks for your attention and I hope you can get the most out of this tutorial, see you soon guys!!! 👋🏽👋🏽👋🏽

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

I'm a passionate software engineer that loves to build projects from scratch and to be continuously learning something new to apply it to real-world projects!
  • Location
    Mexico
  • Joined

More fromOscar Montenegro

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp