I don’t see any code that triggers a state change that would trigger a rerender of the component.
Blazor pages not updating
I am "still" having issues with Blazor behavior.
Looking at my diagram Component 1 is a simple list of items that is populated from the GetData() method which works perfectly. When an edit button is clicked the navigation to component 2 happens and when the Save button is pressed in component 2 we save the information to the database and navigate back to component 1. When the navigation back to component one happens, the GetData() methods is called again but the screen is not updated until I press F5.
I have tried every combination of Task calls, StateHasChanged and finally out of steam and this has caused me days of work.
Here is the code for component 1
using AmaraCode.RainMaker.Models;
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebsiteBlazor.Models;
using WebsiteBlazor.Services;
namespace WebsiteBlazor.Pages.Company
{
public partial class CompanyBroker : ComponentBase
{
[Inject]
public AlertService alertService { get; set; }
[Inject]
public BrokerService brokerService { get; set; }
[Inject]
protected CompanyService companyService { get; set; }
[Inject]
protected UserService userService { get; set; }
//used for the InpustSelect
public List<CompanyBrokerDTO> companyBrokers { get; set; } = new List<CompanyBrokerDTO>();
private UserInfo User { get; set; }
/// <summary>
///
/// </summary>
/// <param name="companyBrokerID"></param>
/// <returns></returns>
public async Task ToggleActive(Guid companyBrokerID)
{
companyService.ToggleCompanyBrokerActive(companyBrokerID);
alertService.addMessage("Active has been toggled");
//repopulate the list
await GetCompanyBrokers();
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public async Task EditCompanyBroker(Guid companyBrokerID)
{
navigationManager.NavigateTo($"/companybroker/edit/{companyBrokerID.ToString()}");
}
protected async override Task OnInitializedAsync()
{
await Task.Run(() => GetCompanyBrokers());
}
/// <summary>
///
/// </summary>
/// <param name="companyBrokerID"></param>
/// <returns></returns>
protected async Task RemoveCompanyBroker(Guid companyBrokerID)
{
companyService.RemoveBrokerFromCompany(companyBrokerID);
await GetCompanyBrokers();
alertService.addMessage("Broker assignment has been removed.");
}
/// <summary>
///
/// </summary>
/// <returns></returns>
private async Task GetCompanyBrokers()
{
User = userService.GetUserInfo();
//companyBrokers = companyService.GetCompanyBrokers(User.CompanyName, User.BrokerName);
companyBrokers = await Task.Run(() => companyService.GetCompanyBrokers(User.CompanyName, User.BrokerName));
}
}
}
Here is the code for component 2:
using AmaraCode.RainMaker.DataService.Abstract;
using AmaraCode.RainMaker.DataService.Domain.Models;
using AmaraCode.RainMaker.Models;
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebsiteBlazor.Models;
using WebsiteBlazor.Services;
namespace WebsiteBlazor.Pages.Company
{
public partial class CompanyBrokerEdit : ComponentBase
{
[Inject]
protected CompanyService companyService { get; set; }
/// <summary>
/// This model is used to populate and send back to the Wrapper service for
/// saving to the database.
/// </summary>
private CompanyBrokerDTO companyBrokerToSave { get; set; }
public CompanyBrokerEditModel editModel { get; set; } = new CompanyBrokerEditModel();
/// <summary>
/// Should be set when editing an entry.
/// </summary>
[ParameterAttribute]
public string EditCompanyBrokerID { get; set; }
protected async override Task OnInitializedAsync()
{
await Task.Run(() => EditCompanyBroker());
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public async Task CancelCompanyBrokerEdit()
{
navigationManager.NavigateTo("/companybroker");
}
/// <summary>
///
/// </summary>
/// <param name="companyBrokerID"></param>
/// <returns></returns>
public async Task EditCompanyBroker()
{
//get the companybroker and populate the form.
var result = companyService.GetCompanyBroker(Guid.Parse(EditCompanyBrokerID));
editModel.ApiKey = result.BrokerApiKey;
editModel.Name = result.Name;
editModel.CompanyBrokerID = result.CompanyBrokerID;
}
/// <summary>
/// Sends the CompanyBrokerEditModel information to the CompanyWrapper
/// to be saved in the Jaylen database.
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task SaveCompanyBroker()
{
//get the latest info from the db.
companyBrokerToSave = companyService.GetCompanyBroker(editModel.CompanyBrokerID);
companyBrokerToSave.Name = editModel.Name;
companyBrokerToSave.BrokerApiKey = editModel.ApiKey;
//Send the model to the company servic that will call the wrapper
await Task.Run(() => companyService.SaveCompanyBroker(companyBrokerToSave));
//navigationManager.NavigateTo("/companybroker");
//call the cancel method so we do not duplicate code
await CancelCompanyBrokerEdit();
}
}
}
2 answers
Sort by: Most helpful
-
-
ICodeInTx 56 Reputation points
2021-07-30T15:12:32.923+00:00 After more extensive stepping the code and verifying the database updates I figured out that the database didn't actually update until after the database read when returning from component 2 to component 1. It turns out the problem wasn't in the read path to the database but in the Save path from component 2.
I had to add .Result on to this line of code to make it work properly
_ = Task.Run(() => _client.PostAsync<CompanyBrokerDTO>(request));
now it looks like this and behaves as it should even though I hear a lot of people say, "don't use .Result"
_ = Task.Run(() => _client.PostAsync<CompanyBrokerDTO>(request)).Result;
Now the task is completing before the "read" from the database when navigating back to component 1.
All this Task stuff is really confusing when it comes to using .Result and if not then how to make the Task run when I want it to.
All the method is doing is calling my API site so here is the entire method:
public void SaveCompanyBroker(CompanyBrokerDTO model) { //Setup the querystring string requestString = $"api/v1/company/companybroker/update/"; //Create the request to send var request = new RestRequest(requestString, Method.PUT, DataFormat.Json); request.AddJsonBody(model); //Get The Response _ = Task.Run(() => _client.PostAsync<CompanyBrokerDTO>(request)).Result; }