Blazor pages not updating

ICodeInTx 56 Reputation points
2021-07-29T16:18:52.627+00:00

I am "still" having issues with Blazor behavior.
119153-image.png
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();  
  
        }  
  
    }  
}  
Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,410 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 57,641 Reputation points
    2021-07-29T18:00:51.583+00:00

    I don’t see any code that triggers a state change that would trigger a rerender of the component.


  2. 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;
            }
    
    0 comments No comments