Nugget 15: Make ChartJs Blazor Bars Display Reliably
Now that this application passed from a "test toy" to an everyday tool, defects are showing up.
Bug: Accessing the Chart data after creating a new record does not load any data. Several problems with this going from the Blazor component lifecycle to how the view model was registered in the DI container.
This post works as a "release document" for the changes required.
Config Initialization
Config = new BarConfig() created in the constructor and Config.Data.Labels / Config.Data.Datasets cleared.
Reason: ChartJs.Blazor exposes Data as a read-only property; ensure Labels/Datasets exist before use to avoid null reference exceptions.
Remove Manual Chat Initialization In The ViewModel
The model does not need to initialize the Chart. This is because the Razor page uses @ref=ViewModel.Chart, providing the real instance. The rendered provides the instance when the @ref is used. If the VM initializes the component, this can create rendering problems, which it was.
Load Data
The mechanism has changed to better acomodate to the MVVM Pattern. Note that now the IHomeViewModel inherits from IAsyncInitialization, which contains only one signature, Task InitializeAsync().
When HomeViewModel implements this interface, this is when the data is loaded. Previously, the data was loaded in the constructor. Perhaps, loading the data in the constructor would have been OK by changing the service from AddScoped to AddTransient. I did not test that because I think the new implementation is the correct one.
Also note how the labels are being built. Cleaner
Other Changes
Many changes are making the graph look much better. Note that now Ticks.BeginAtZSero is true and Min = 0. Previously, it started at one (1), and single chart entries were "hidden".
Lifecycle
This is the most important change. ViewModel.InitializeAsync() runs and LoadData() populates Config before the first render.
For a good measure, in Program.cs:
builder.Services.AddScoped<IIndexViewModel, IndexViewModel>().AddTransient<IHomeViewModel, HomeViewModel>();
The View
The Home.razor view is different and renders the view model according to what the ViewModelBase dictates.
Comments
Post a Comment