Home > Blockchain >  Blazor trying to resolve variables in HTML before executing code?
Blazor trying to resolve variables in HTML before executing code?

Time:08-08

I am writing a practice app in Blazor , utilizing an API that I wrote. I am attempting to load user information in a "profile" page. I have the API call in a service class but the execution order seems to be weird resulting in a null reference?

Profile Page:

@page "/profile"
@inject AuthenticationStateProvider AuthStateProvider
@inject UserService _UserService

if(user.equals(null)) 
{
    <span>@message</span>
}
else{
    <h2>Hello @user.Username</h2>

    <div class=container>
        <div >
            <img src=""/>
            <p>@user.Bio</p>
        </div>
    </div>
}
@code {
    private User? user = null;
    private string message;
    protected override async Task OnInitializedAsync()
    {
        var authstate = await AuthStateProvider.GetAuthenticationStateAsync();

        //var currentUserId = "1";
        var currentUserId = authstate.User.Identities.First().Claims.FirstOrDefault(c => c.Type == "nameid").Value;
        var result = await _UserService.GetUserById(Int32.Parse(currentUserId));
        if(!result.Success)
        {
            message = result.Message;
        }
        else 
        {
            user = result.Data;
        }
    }
}

User class:

    public class User
    {
        [JsonPropertyName("id")]
        public int Id { get; set; }
        [JsonPropertyName("username")]
        public string Username { get; set; }      
        [JsonPropertyName("email")]
        public string Email { get; set; }
        [JsonPropertyName("profilePicture")]
        public string ProfilePicture { get; set; }
        [JsonPropertyName("bio")]
        public string Bio { get; set; }
        [JsonPropertyName("firstName")]
        public string FirstName { get; set; }
        [JsonPropertyName("lastName")]
        public string LastName { get; set; }
        [JsonPropertyName("createdAt")]
        public DateTime CreatedAt {get; set;}
        [JsonPropertyName("lastUpdated")]
        public DateTime LastUpdated { get; set; }
    }
}

UserService class:

    public class UserService
    {
        private readonly HttpClient _http;
        private readonly AuthenticationStateProvider _authStateProvider;

        public UserService(HttpClient http, AuthenticationStateProvider authStateProvider)
        {
            _http = http;
            _authStateProvider = authStateProvider;
        }

        public async Task<ServiceResponse<List<User>>> GetUsers()
        {
            var result = await _http.GetFromJsonAsync<ServiceResponse<List<User>>>($"/User");
            return result;
        }

        public async Task<ServiceResponse<User>> GetUserById(int id)
        {
            var result = await _http.GetFromJsonAsync<ServiceResponse<User>>($"/User/GetById/{id}");
            return result;
        }
    }
}

In the profile page, when I debug this, the debugger goes straight from

protected override async Task OnInitializedAsync()
    {
        var authstate = await AuthStateProvider.GetAuthenticationStateAsync();

to

<h2>Hello @user.Username</h2>

complaining that user is null. Why isn't the function OnInitializedAsync() being fully executed before trying to render the HTML where user.Username is being called? I expect user to be null at this point because the code that sets it seems to be getting skipped?

CodePudding user response:

If you Razor code has the following logic:

@if(user is null)
{
   // display a message
}
else
{
   // show some user info
}

Then you cannot get to Show some user info if user is null. Therefore there must be something wrong with your logic.

On you second comment:

var authstate = await AuthStateProvider.GetAuthenticationStateAsync();

The await yields, so ComponentBase will initiate it's first render event which is what you are seeing. At this point User is null so you should see message (which appears to be null at this point in the proceedings - but not declared string?).

  • Related