0

I built an API in ASP.NET Core and the code looks like this:

public async Task<IEnumerable<Applicant>> GetApplicants()
{
    return await appDbContext.Applicants.ToListAsync();
}

[HttpGet]
public async Task<ActionResult> GetApplicants()
{
    try
    {
        return Ok(await applicantRepository.GetApplicants());
    }
    catch (Exception)
    {
        return StatusCode(StatusCodes.Status500InternalServerError, "Error retreiving data from the database");
    }
}

Here we have how it looks in browser(guess that is fine):

enter image description here

Blazor (server) code:

public interface IApplicantService
{
    Task<IEnumerable<Applicant>> GetApplicants();
}

public class ApplicantService : IApplicantService
{
    private readonly HttpClient httpClient;
    public ApplicantService(HttpClient httpClient)
    {
        this.httpClient = httpClient;
    }
    public async Task<IEnumerable<Applicant>> GetApplicants()
    {
        return await httpClient.GetJsonAsync<Applicant[]>("api/applicants");
    }
}

public class ApplicantList : ComponentBase
{
    [Inject]
    public IApplicantService ApplicantService { get; set; }
    public IEnumerable<Applicant> Applicants { get; set; }

    protected override async Task OnInitializedAsync()
    {        
        Applicants = (await ApplicantService.GetApplicants()).ToList();
    }
}

And the page:

@page "/"
@inherits ApplicantList
<h1>Applicants</h1>

<div class="card-deck">
    @foreach (var applicant in Applicants)
    {
        <div class="card m-3" style="min-width: 18rem; max-width:30.5%;">
            <div class="card-header">
                <h3>@applicant.Name</h3>
            </div>
            <div class="card-footer text-center">
                <a href="#" class="btn btn-primary m-1">View</a>

                <a href="#" class="btn btn-primary m-1">Edit</a>

                <a href="#" class="btn btn-danger m-1">Delete</a>
            </div>
        </div>
    }
</div>

I am facing null reference error. While debugging I see that Applicants is null

James Z
  • 12,209
  • 10
  • 24
  • 44
Alex C
  • 13
  • 1

1 Answers1

0

The solution to this is simple: wrap the foreach loop with an if statement like this:

@if( Applicants != null)
   {
       @foreach (var applicant in Applicants)
       {
        //...
       }
   }

Explanation: When you call the ApplicantService.GetApplicants() method in the lifecycle OnInitializedAsync method, the following occurs:

ApplicantService.GetApplicants() is called and awaited, the execution control is yielded to the calling code, till GetApplicants() completes...Blazor starts rendering the view portion of your component, but alas, the Applicants variable is not yet populated with data. It contains the null value, thus the exception.

Note: that when the GetApplicants() method completes, re-rendering occurs again, this time the Applicants variable contains the retrieved data.

Note: Don't use the GetJsonAsync method. Use instead the new set of methods and objects: Install-Package System.Net.Http.Json -Version 5.0.0

enet
  • 41,195
  • 5
  • 76
  • 113
  • 1
    That was so easy and clear... I am so sorry for my ignorance and for taking Your time, sir! Thank You so much! – Alex C Mar 22 '21 at 11:28
  • You're welcome. You do not have to apologize...many developers faced this problem, including me. One needs to be specifically told about what lead to this exception, even if you are familiar with the life cycle of the Razor Component Model... Would you mind marking it as the answer if it solved your problem, so others know it was useful. (make the dimmed check icon green and upvote the answer) – enet Mar 22 '21 at 11:34
  • 1
    Sure! And Again thank You, You saved my day! – Alex C Mar 22 '21 at 19:15