Concept: Component Lifecycle and OnInitializedAsync()

Blazor components follow a lifecycle as they are created, rendered, updated, and removed. Lifecycle methods let you run code at specific points in that process.

One useful method is OnInitializedAsync(). It is commonly used to load initial data asynchronously when a component first initializes.

Demo explanation

Consider a simple page that displays a list of books. When the page opens, the component requests the book list from an API. While the request is running, it displays a loading message. Once the request finishes, it displays the books returned by the API.

@page "/demo-books" @using System.Net.Http.Json @inject HttpClient Http <h3>Book List</h3> @if (isLoading) { <p>Loading books...</p> } else if (books.Count == 0) { <p>No books were found.</p> } else { <ul> @foreach (var book in books) { <li>@book.Title</li> } </ul> } @code { private List<BookSummary> books = new(); private bool isLoading = true; protected override async Task OnInitializedAsync() { try { books = await Http.GetFromJsonAsync<List<BookSummary>>( "api/Books") ?? new(); } finally { isLoading = false; } } private sealed class BookSummary { public string Title { get; set; } = string.Empty; } } 

In this example, OnInitializedAsync() runs when the component initializes and loads the book list. The isLoading variable determines whether the loading message or the results are displayed. The example assumes that the API returns objects with a Title property.

This lifecycle method is useful whenever a component needs initial data before presenting its main content. User-triggered operations, such as clicking a button to refresh the list, can instead be handled by event methods.

MY SUBSCRIPTIONS= using GymManagement.Application.DTOs; using GymManagement.Application.Services; using GymManagement.Domain.RepositoryContracts; namespace GymManagement.Application.Services.Implementation; public class SubscriptionService : ISubscriptionService { private readonly ISubscriptionRepository _subscriptionRepository; public SubscriptionService( ISubscriptionRepository subscriptionRepository) { _subscriptionRepository = subscriptionRepository; } public async Task<List<MyMembershipResponseDto>> GetMyMembershipsAsync( Guid userId, CancellationToken cancellationToken) { if (userId == Guid.Empty) { return new List<MyMembershipResponseDto>(); } var subscriptions = await _subscriptionRepository.GetMyMembershipsAsync( userId, cancellationToken); var today = DateOnly.FromDateTime(DateTime.UtcNow); return subscriptions.Select(s => { // Derive an expired display status if the stored status // has not yet been updated by a background process. var displayStatus = s.Status; if (s.Status == "Active" && s.EndDate < today) { displayStatus = "Expired"; } // Example UI policy: allow cancellation only while active // and before the expiry date. var canCancel = displayStatus == "Active" && s.StartDate <= today && s.EndDate >= today; // Example UI policy: allow renewal for active or expired // memberships, but not pending or cancelled ones. var canRenew = displayStatus == "Active" || displayStatus == "Expired"; return new MyMembershipResponseDto { SubscriptionId = s.Id, GymName = s.GymCenter.GymName, PlanName = s.MembershipPlan.PlanName, StartDate = s.StartDate, ExpiryDate = s.EndDate, SubscriptionStatus = displayStatus, CanRenew = canRenew, CanCancel = canCancel }; }).ToList(); } } ======================================================================================================================= using GymManagement.Domain.Entities; using GymManagement.Domain.RepositoryContracts; using GymManagement.Infrastructure.Context; using Microsoft.EntityFrameworkCore; namespace GymManagement.Infrastructure.Repository; public class SubscriptionRepository : ISubscriptionRepository { private readonly AppDbContext _context; public SubscriptionRepository(AppDbContext context) { _context = context; } public async Task<List<Subscription>> GetMyMembershipsAsync( Guid userId, CancellationToken cancellationToken) { return await _context.Subscriptions .AsNoTracking() .Where(s => s.UserId == userId && !s.IsDeleted) .Include(s => s.GymCenter) .Include(s => s.MembershipPlan) .OrderByDescending(s => s.SubscribedOn) .ToListAsync(cancellationToken); } } =============================================================================================================================== Attendace table public class Attendance { public Guid Id { get; set; } public Guid UserId { get; set; } public Guid GymId { get; set; } public Guid SubscriptionId { get; set; } public DateTime AttendanceDate { get; set; } // Navigation properties public ApplicationUser User { get; set; } = null!; public GymCenter GymCenter { get; set; } = null!; public Subscription Subscription { get; set; } = null!; } ============================================================== modelBuilder.Entity<Attendance>() .HasOne(a => a.User) .WithMany(u => u.Attendances) .HasForeignKey(a => a.UserId) .OnDelete(DeleteBehavior.Restrict); // GymCenter 1 -> many Attendances modelBuilder.Entity<Attendance>() .HasOne(a => a.GymCenter) .WithMany(g => g.Attendances) .HasForeignKey(a => a.GymId) .OnDelete(DeleteBehavior.Restrict); // Subscription 1 -> many Attendances modelBuilder.Entity<Attendance>() .HasOne(a => a.Subscription) .WithMany(s => s.Attendances) .HasForeignKey(a => a.SubscriptionId) .OnDelete(DeleteBehavior.Restrict); using YourProject.Application.Features.Attendance.Queries.MyAttendance; using YourProject.Application.ServicesContracts; using YourProject.Domain.RepositoryContracts; namespace YourProject.Application.Services; public class AttendanceService : IAttendanceService { private readonly IAttendanceRepository _attendanceRepository; public AttendanceService( IAttendanceRepository attendanceRepository) { _attendanceRepository = attendanceRepository; } public async Task<MyAttendanceResponseDto> GetMyAttendanceAsync( Guid userId, CancellationToken cancellationToken) { if (userId == Guid.Empty) { throw new ArgumentException( "Invalid user ID.", nameof(userId)); } var totalAttendanceCount = await _attendanceRepository.GetTotalAttendanceCountAsync( userId, cancellationToken); return new MyAttendanceResponseDto { TotalAttendanceCount = totalAttendanceCount }; } } ====================================================== using Microsoft.EntityFrameworkCore; using YourProject.Domain.RepositoryContracts; using YourProject.Infrastructure.Context; namespace YourProject.Infrastructure.Repository; public class AttendanceRepository : IAttendanceRepository { private readonly AppDbContext _context; public AttendanceRepository(AppDbContext context) { _context = context; } public async Task<int> GetTotalAttendanceCountAsync( Guid userId, CancellationToken cancellationToken) { return await _context.Attendances .AsNoTracking() .CountAsync( a => a.UserId == userId, cancellationToken); } } =================================================================================== program.cs builder.Services.AddBlazoredLocalStorage(); builder.Services.AddAuthorizationCore(); builder.Services.AddCascadingAuthenticationState(); builder.Services.AddScoped<AuthenticationStateProvider,CustomAuthStateProvider>(); builder.Services.AddScoped<JwtAuthorizationHandler>(); builder.Services.AddScoped<ShowErrors>(); builder.Services.AddSweetAlert2(); builder.Services.AddScoped(sp => { var handler = sp.GetRequiredService<JwtAuthorizationHandler>(); handler.InnerHandler = new HttpClientHandler(); return new HttpClient(handler) { BaseAddress = new Uri("https://localhost:7041/api/") }; }); =================================================================== ===FOR GYMCard error show================== private async Task ShowMessageAsync( string title, string message, bool success) { await Swal.FireAsync(new SweetAlertOptions { Title = title, Text = message, Icon = success ? SweetAlertIcon.Success : SweetAlertIcon.Error }); } ================================================================= CANCELL SUBSCRIPTION public async Task<SubscriptionCommandResponse> CancelSubscriptionAsync( Guid subscriptionId, Guid userId, CancellationToken cancellationToken) { var subscription = await _subscriptionRepository.GetByIdAsync( subscriptionId, cancellationToken); if (subscription is null) { return new SubscriptionCommandResponse { Success = false, Message = "Subscription not found." }; } // Rule 1: A user can cancel only their own subscription. if (subscription.UserId != userId) { return new SubscriptionCommandResponse { Success = false, Message = "You cannot cancel another user's subscription." }; } // Rule 2: Only active subscriptions can be cancelled. if (subscription.Status != "Active") { return new SubscriptionCommandResponse { Success = false, Message = "Only active subscriptions can be cancelled." }; } // Rule 3: Calculate the refund based on the start date. var today = DateOnly.FromDateTime(DateTime.UtcNow); var daysSinceStart = today.DayNumber - subscription.StartDate.DayNumber; decimal refundPercentage = daysSinceStart >= 0 && daysSinceStart <= 7 ? 80m : 0m; decimal refundAmount = Math.Round( subscription.PricePaid * refundPercentage / 100m, 2); // Rule 4: Cancel the subscription and record the refund. subscription.Status = "Cancelled"; // Add these properties to the entity if you want to persist them. subscription.RefundAmount = refundAmount; subscription.CancelledAt = DateTime.UtcNow; await _subscriptionRepository.UpdateAsync( subscription, cancellationToken); return new SubscriptionCommandResponse { Success = true, RefundAmount = refundAmount, RefundPercentage = refundPercentage, Message = refundPercentage > 0 ? $"Subscription cancelled. You are eligible for an 80% refund of {refundAmount:C}." : "Subscription cancelled. No refund is available after the first 7 days." }; } ============================================================================== <AuthorizeView> <Authorized> <div class="sidebar">  <NavMenu /> </div> </Authorized> </AuthorizeView> ======================================================================= IN GYMCARD.RAZOR <button type="button" class="btn btn-primary mt-auto"  @onclick="ViewPlans"> <i class="bi bi-card-list me-1"></i>  View Plans </button> [Parameter] public bool IsAdmin { get; set; } [Parameter] public EventCallback<Guid> OnViewPlans { get; set; } private Task ViewPlans() => OnViewPlans.InvokeAsync(Id); IN BROWSE GYMS=== <BrowseGymCard Id="@gym.Id" GymName="@gym.GymName" Address="@gym.Address" CityName="@gym.CityName" Phone="@gym.Phone" Email="@gym.Email" OpeningTime="@gym.OpeningTime" ClosingTime="@gym.ClosingTime" TotalClassCapacity="@gym.TotalClassCapacity" LockerFacility="@gym.LockerFacility" ParkingAvailable="@gym.ParkingAvailable" Status="@gym.Status" OnViewPlans="ViewPlans" /> In BrowseGyms.razor (User page): <GymCard Id="@gym.Id" GymName="@gym.GymName" IsAdmin="false" OnViewPlans="ViewPlans" /> @code { private void ViewPlans(Guid gymId) { Navigation.NavigateTo($"/gym-membership-plans/{gymId}"); } // Keep your existing methods and properties here. } ManageGyms.razor (Admin page): <GymCard Id="@gym.Id" GymName="@gym.GymName" IsAdmin="true" OnEdit="EditGym" OnDelete="DeleteGym" /> @page "/gym-membership-plans/{GymId:guid}" ======================================================================================== NAVMENU @using Microsoft.AspNetCore.Components.Authorization <div class="top-row ps-3 navbar navbar-dark bg-secondary">  <div class="container-fluid">  <a class="navbar-brand" href="">Gym Management</a>  <button title="Navigation menu" class="navbar-toggler"  @onclick="ToggleNavMenu"> <span class="navbar-toggler-icon"></span>  </button> </div> </div> <div class="@NavMenuCssClass bg-secondary nav-scrollable shadow"  @onclick="ToggleNavMenu"> @* ADMIN SIDEBAR *@ <AuthorizeView Roles="Admin"> <Authorized> <nav class="nav flex-column">  <div class="nav-item px-3 p-1 shadow">  <NavLink class="nav-link"  href="" Match="NavLinkMatch.All"> <i class="Source:https://dev.to/lorcan_grover/blazor-documentation-component-lifecycle-592e

Related posts