These gists are part of the article: https://blog.georgekosmidis.net/2021/11/10/create-and-use-your-first-component-in-blazor/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<p>Current count: @currentCount</p> | |
<button class="btn btn-primary" onclick="@IncrementCount">Click me</button> | |
@code { | |
int currentCount = 0; | |
void IncrementCount() | |
{ | |
currentCount++; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@page "/" | |
<!-- Add a using to locate the component --> | |
@using Blazor.WeatherWidget | |
<!-- Add the component --> | |
<Component1 /> | |
<h1>Hello, world!</h1> | |
Welcome to your new app. | |
<SurveyPrompt Title="How is Blazor working for you?" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"coord": { | |
"lon": 11.5755, | |
"lat": 48.1374 | |
}, | |
"weather": [ | |
{ | |
"id": 803, | |
"main": "Clouds", | |
"description": "broken clouds", | |
"icon": "04d" | |
} | |
], | |
"base": "stations", | |
"main": { | |
"temp": 291.89, | |
"feels_like": 291.49, | |
"temp_min": 289.13, | |
"temp_max": 293.5, | |
"pressure": 1020, | |
"humidity": 64 | |
}, | |
"visibility": 10000, | |
"wind": { | |
"speed": 0.89, | |
"deg": 168, | |
"gust": 3.13 | |
}, | |
"clouds": { | |
"all": 77 | |
}, | |
"dt": 1625219902, | |
"sys": { | |
"type": 2, | |
"id": 2002112, | |
"country": "DE", | |
"sunrise": 1625195889, | |
"sunset": 1625253422 | |
}, | |
"timezone": 7200, | |
"id": 2867714, | |
"name": "Munich", | |
"cod": 200 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); | |
public class Coord | |
{ | |
[JsonProperty("lon")] | |
public double Lon { get; set; } | |
[JsonProperty("lat")] | |
public double Lat { get; set; } | |
} | |
public class Weather | |
{ | |
[JsonProperty("id")] | |
public int Id { get; set; } | |
[JsonProperty("main")] | |
public string Main { get; set; } | |
[JsonProperty("description")] | |
public string Description { get; set; } | |
[JsonProperty("icon")] | |
public string Icon { get; set; } | |
} | |
public class Main | |
{ | |
[JsonProperty("temp")] | |
public double Temp { get; set; } | |
[JsonProperty("feels_like")] | |
public double FeelsLike { get; set; } | |
[JsonProperty("temp_min")] | |
public double TempMin { get; set; } | |
[JsonProperty("temp_max")] | |
public double TempMax { get; set; } | |
[JsonProperty("pressure")] | |
public int Pressure { get; set; } | |
[JsonProperty("humidity")] | |
public int Humidity { get; set; } | |
} | |
public class Wind | |
{ | |
[JsonProperty("speed")] | |
public double Speed { get; set; } | |
[JsonProperty("deg")] | |
public int Deg { get; set; } | |
[JsonProperty("gust")] | |
public double Gust { get; set; } | |
} | |
public class Clouds | |
{ | |
[JsonProperty("all")] | |
public int All { get; set; } | |
} | |
public class Sys | |
{ | |
[JsonProperty("type")] | |
public int Type { get; set; } | |
[JsonProperty("id")] | |
public int Id { get; set; } | |
[JsonProperty("country")] | |
public string Country { get; set; } | |
[JsonProperty("sunrise")] | |
public int Sunrise { get; set; } | |
[JsonProperty("sunset")] | |
public int Sunset { get; set; } | |
} | |
public class Root | |
{ | |
[JsonProperty("coord")] | |
public Coord Coord { get; set; } | |
[JsonProperty("weather")] | |
public List<Weather> Weather { get; set; } | |
[JsonProperty("base")] | |
public string Base { get; set; } | |
[JsonProperty("main")] | |
public Main Main { get; set; } | |
[JsonProperty("visibility")] | |
public int Visibility { get; set; } | |
[JsonProperty("wind")] | |
public Wind Wind { get; set; } | |
[JsonProperty("clouds")] | |
public Clouds Clouds { get; set; } | |
[JsonProperty("dt")] | |
public int Dt { get; set; } | |
[JsonProperty("sys")] | |
public Sys Sys { get; set; } | |
[JsonProperty("timezone")] | |
public int Timezone { get; set; } | |
[JsonProperty("id")] | |
public int Id { get; set; } | |
[JsonProperty("name")] | |
public string Name { get; set; } | |
[JsonProperty("cod")] | |
public int Cod { get; set; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Startup | |
{ | |
public Startup(IConfiguration configuration) | |
{ | |
Configuration = configuration; | |
} | |
//... | |
public void ConfigureServices(IServiceCollection services) | |
{ | |
services.AddRazorPages(); | |
services.AddServerSideBlazor(); | |
//Adds an IHttpClientFactory and all related services | |
// and configures the bindings between the WeatherService | |
// and a named HttpClient | |
services.AddHttpClient<WeatherService>() | |
//Sets the time that the HttpMessageHandler can be reused | |
.SetHandlerLifetime(TimeSpan.FromMinutes(5)); | |
} | |
//... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class WeatherService | |
{ | |
private readonly HttpClient _httpClient; | |
public WeatherService(HttpClient httpClient) | |
{ | |
_httpClient = httpClient; | |
} | |
public async Task<Root> Get(string query, string key) | |
{ | |
var request = new HttpRequestMessage(HttpMethod.Get, $"http://api.openweathermap.org/data/2.5/weather?q={query}&APPID={key}"); | |
request.Headers.Add("User-Agent", "Blazor-Weather-Sample"); | |
request.Headers.Add("X-Code-Source", "https://github.com/georgekosmidis/Blazor.WeatherWidget"); | |
var response = await _httpClient.SendAsync(request); | |
var result = new Root(); | |
if (response.IsSuccessStatusCode) | |
{ | |
var responseString = await response.Content.ReadAsStringAsync(); | |
result = JsonConvert.DeserializeObject<Root>(responseString); | |
} | |
return result; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@using Blazor.WeatherWidget.Services; | |
@using Blazor.WeatherWidget.Models; | |
@inject IWeatherService service; | |
<div>@Math.Round(result.Main.Temperature, 1) °C</div> | |
@code { | |
private Root result; | |
protected override async Task OnInitializedAsync() | |
{ | |
result = await service.Get("Munich, DE", "XXXXXXXXXXXXXXXXXXXXXXX"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@using Blazor.WeatherWidget.Services; | |
@using Blazor.WeatherWidget.Models; | |
@inject IWeatherService service; | |
@if (result == null) | |
{ | |
<p><em>Loading...</em></p> | |
} | |
else | |
{ | |
<div>@Math.Round(result.Main.Temperature, 1) °C</div> | |
} | |
@code { | |
private Root result; | |
protected override async Task OnInitializedAsync() | |
{ | |
result = await service.Get("Munich, DE", "XXXXXXXXXXXXXXXXXXXXXXX"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@using Blazor.WeatherWidget.Services; | |
@using Blazor.WeatherWidget.Models; | |
@inject IWeatherService service; | |
@if (result == null) | |
{ | |
<p><em>Loading...</em></p> | |
} | |
else | |
{ | |
<div>@Math.Round(result.Main.Temperature, 1) °C</div> | |
<!-- Add an input that is bound to the new property CurrentCity --> | |
<input value="@CurrentCity" @oninput="@((e) => { CurrentCity = (string)e.Value;})"> | |
<!-- Add a button that onclick runs an event to retrieve data for the typed city --> | |
<button class="btn btn-info" type="button" @onclick="OnSearchNewCity">Go!</button> | |
} | |
@code { | |
private Root result; | |
public string CurrentCity { get; set; } = "Munich, DE"; | |
protected override async Task OnInitializedAsync() | |
{ | |
result = await service.Get(CurrentCity, "XXXXXXXXXXXXXXXXXXXXXXX"); | |
} | |
protected async Task OnSearchNewCity() | |
{ | |
//I know, its the same as OnInitializedAsync, but let's move on for now | |
result = await service.Get(CurrentCity, "XXXXXXXXXXXXXXXXXXXXXXX"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@using Blazor.WeatherWidget.Services; | |
@using Blazor.WeatherWidget.Models; | |
@inject IWeatherService service; | |
<!-- That's our default tempate --> | |
@{ | |
RenderFragment defaultTemplate = | |
@<div> | |
@if (result != null) | |
{ | |
<div>@Math.Round(result.Main.Temperature, 1) °C</div> | |
<!-- Add an input that is bound to the new property CurrentCity --> | |
<input value="@CurrentCity" @oninput="@((e) => { CurrentCity = (string)e.Value; })"> | |
<!-- Add a button that onclick runs an event to retrieve data for the typed city --> | |
<button class="btn btn-info" type="button" @onclick="OnSearchNewCity">Go!</button> | |
} | |
</div>; <!-- Mind the semicolon here, it marks the end of our template! --> | |
} | |
@if (result == null) | |
{ | |
//We can define a new template for loading too! | |
<p><em>Loading...</em></p> | |
} | |
else | |
{ | |
//If dev didnt define one, lets use ours | |
if (CustomTemplate == null) | |
{ | |
@defaultTemplate | |
} | |
else | |
{ | |
@CustomTemplate(result); | |
} | |
} | |
@code { | |
private Root result; | |
//A public parameter, exactly as we did with the CurrentCity parameter | |
[Parameter] | |
public RenderFragment<Root> CustomTemplate { get; set; } | |
[Parameter] | |
public string CurrentCity { get; set; } = "Munich, DE"; | |
protected override async Task OnInitializedAsync() | |
{ | |
result = await service.Get(CurrentCity, "XXXXXXXXXXXXXXXXXXXXXXX"); | |
} | |
protected async Task OnSearchNewCity() | |
{ | |
//I know, its the same as OnInitializedAsync, but let's move on for now | |
result = await service.Get(CurrentCity, "XXXXXXXXXXXXXXXXXXXXXXX"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@page "/" | |
@using Blazor.WeatherWidget | |
<!-- Showing weather with the default template --> | |
<WeatherWidget CurrentCity="London, UK" /> | |
<!-- Using a custom template --> | |
<WeatherWidget CurrentCity="Munich, DE"> | |
<CustomTemplate> | |
That's my weather in Munich: <strong>@Math.Round(context.Main.Temperature, 1) °C</strong> | |
</CustomTemplate> | |
</WeatherWidget> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@using Blazor.WeatherWidget.Services; | |
@using Blazor.WeatherWidget.Models; | |
@inject IWeatherService service; | |
<!-- That's our default tempate --> | |
@{ | |
RenderFragment defaultTemplate = | |
@<div> | |
@if (result != null) | |
{ | |
<div>@Math.Round(result.Main.Temperature, 1) °C</div> | |
<!-- Add an input that is bound to the new property CurrentCity --> | |
<input value="@CurrentCity" @oninput="@((e) => { CurrentCity = (string)e.Value; })"> | |
<!-- Add a button that onclick runs an event to retrieve data for the typed city --> | |
<button class="btn btn-info" type="button" @onclick="OnSearchNewCity">Go!</button> | |
} | |
</div>; <!-- Mind the semicolon here, it marks the end of our template! --> | |
} | |
@if (result == null) | |
{ | |
//We can define a new template for loading too! | |
<p><em>Loading...</em></p> | |
} | |
else | |
{ | |
//If dev didnt define one, lets use ours | |
if (CustomTemplate == null) | |
{ | |
@defaultTemplate | |
} | |
else | |
{ | |
@CustomTemplate(result); | |
} | |
} | |
@code { | |
private Root result; | |
//A public parameter, exactly as we did with the CurrentCity parameter | |
[Parameter] | |
public RenderFragment<Root> CustomTemplate { get; set; } | |
[Parameter] | |
public string CurrentCity { get; set; } = "Munich, DE"; | |
[Parameter] | |
//This provides support for two-way binding from parent component e.g. <WeatherWidget @bind-CurrentCity="@currentCity" /> | |
public EventCallback<string> CurrentCityChanged { get; set; } | |
protected override async Task OnParametersSetAsync() | |
{ | |
await PopulateWeatherDataAsync(); | |
} | |
protected async Task OnSearchNewCity() | |
{ | |
await PopulateWeatherDataAsync(); | |
} | |
private async Task PopulateWeatherDataAsync() | |
{ | |
result = await service.Get(CurrentCity, "XXXXXXXXXXXXXXXXXXXXXXX"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@page "/" | |
@using Blazor.WeatherWidget | |
<!-- Showing weather with the default template --> | |
<WeatherWidget CurrentCity="London, UK" /> | |
<br /><br /><br /> | |
<!-- Using a custom template --> | |
<WeatherWidget @bind-CurrentCity="@myCityBinding"> | |
<CustomTemplate> | |
That's the temperature in @myCityBinding: <strong>@Math.Round(context.Main.Temperature, 1) °C</strong> | |
<br /> | |
<input value="@myCity" @oninput="@((e) => { myCity = (string)e.Value; })"> | |
<button class="btn btn-info" type="button" @onclick="OnSearchNewCity">Search for a new temperature!</button> | |
</CustomTemplate> | |
</WeatherWidget> | |
@code { | |
private string myCity = "Tokyo"; | |
private string myCityBinding = "Tokyo"; | |
protected void OnSearchNewCity() | |
{ | |
myCityBinding = myCity; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment