Search code examples
c#razorblazor

Blazor properly updating the UI after an API call


This code does exactly what I want:

  1. Displays a message (div) from the robot saying thinking
  2. Waits for the API call to complete updates that message (div) and scrolls to the message (div)

It feels like this would fail a code review though even though it does exactly what I need.

Is there some better pattern to accomplish this showing the div with "thinking" until the API call is complete.

private async Task SendMessage()
{   
    var messageHolder = userMessage;
    Console.WriteLine($"User Message is: {userMessage}");

    if (!string.IsNullOrWhiteSpace(messageHolder))
    {
        messages.Add(new ChatMessageInPage { User = "User", Message = messageHolder });
        var msg = new ChatMessageInPage { User = "Robot 🤖", Message = "Thinking..." };
        messages.Add(msg);
        userMessage = string.Empty;
        // THS IS THE ODD CODE
        Task.Run( async () =>
            {
                msg.Message =  await apiRobot.GetBotResponse(messageHolder);
          
                InvokeAsync(() =>
                {
                    NeedScrollBottom = true;
                    StateHasChanged();
                });
            }
        );
        NeedScrollBottom = true;
        StateHasChanged();
    }
}

Solution

  • Normally this should do the same in a simpler and more reliable way:

    if (!string.IsNullOrWhiteSpace(messageHolder))
    {
        messages.Add(new ChatMessageInPage { User = "User", Message = messageHolder });
        var msg = new ChatMessageInPage { User = "Robot 🤖", Message = "Thinking..." };
        messages.Add(msg);
        userMessage = string.Empty;
    
        // Simple code - display previous during await
        NeedScrollBottom = true;
        await Task.Delay(1);  // recommended, for when the apiRobot isn't async enough            
        msg.Message =  await apiRobot.GetBotResponse(messageHolder);      
        NeedScrollBottom = true;
    }
    

    when this does not work as expected then post the exact results.