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
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.