Home > Net >  UI Elements only update when focus is moved away from original button/input
UI Elements only update when focus is moved away from original button/input

Time:12-05

I am having an issue where I would press a button and a response would be given from the server but the UI would not update to display the response I have set for it until I start interacting with something else. Can't seem to figure out what is causing this. Been going through the code, making changes in terms of the UI layout but nothing seemed to work. I have a gif here to better demonstrate. I have tried using StateHasChanged but this did not seem to work either

enter image description here

Razor page

<EditForm Model="@AssignUser" OnValidSubmit="@AddUserToProject">

@*    <DataAnnotationsValidator />*@
<div >
    <label > Assign Users </label>
    <InputText placeholder="Username" id="inlineFormInputGroup" type="email" @bind-Value="@AssignUser.UserName"  />

    <button type="submit" >Add</button>
</div>
</EditForm>
//display messages depending on outcome
@if (userNotFoundError == true)
{
    <div  role="alert">
        User could not be found
    </div>
}

@if (userExistsAlready == true)
{
    <div  role="alert">
        User is already on the project
    </div>
}

Add user to project function

private bool userNotFoundError = false;
private bool userExistsAlready = false;
private async void AddUserToProject()
{
    try
    {
        var response = await Http.PutAsJsonAsync($"Projects/add/User/{AssignUser.UserName}/{projectItem.ProjectId}", AssignUser);

        // Attempt add adding someone who is already on the project?
        if (response.StatusCode == HttpStatusCode.Forbidden)
        {
            StateHasChanged();

            if (userNotFoundError == true)
            {
                userNotFoundError = false;
            }
            userExistsAlready = true;

            
        }
// Attempt at adding someone who does not exist as a user?
        else if (response.StatusCode == HttpStatusCode.BadRequest)
        {
            StateHasChanged();

            if (userExistsAlready == true)
            {
                userExistsAlready = false;
            }
            userNotFoundError = true;
        }
        else
        {
            var content = await response.Content.ReadAsStringAsync();
            var userobject = JsonConvert.DeserializeObject<ApplicationUser>(content);
            response.EnsureSuccessStatusCode();
            Navigation.NavigateTo("/projects");
            userNotFoundError = false;
            userExistsAlready = false;
            StateHasChanged();
        }

    }
    catch (Exception e)
    {
        userNotFoundError = true;
    }
}

Add user function in controller

[HttpPut("add/User/{userName}/{projID}")]
public async Task<IActionResult> AddUserToProject(string userName, Guid projID)
{

    var project = _context.Projects.Include(u => u.AssignedUsersToProject).FirstOrDefault(p => p.ProjectId.ToString().Equals(projID.ToString()));

    try
    {
        var user = _context.Users.First(u => u.UserName.Equals(userName));

        if (!project.AssignedUsersToProject.Any(u => u.UserName.Equals(user.UserName))) { 
            project.AssignedUsersToProject.Add(user);                    
        } else
        {
            return Forbid();
        }
    }
    catch (InvalidOperationException)
    {
        return BadRequest();
    }

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!ProjectExists(projID))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }

    return NoContent();
}

CodePudding user response:

Change

private async void AddUserToProject()

to

private async Task AddUserToProject()

and it should work.

You can then also remove all those StateHasChanged() calls, they serve no purpose anymore.

Blazor does not know when an async void is completed. When you use an async Task method then Blazor will automatically rerender your UI when the method is finished.

But I do suspect there is another problem with showing the error. The StateHasChanged() calls should have 'repaired' the async void for most branches.

  • Related