0

I'm new to Blazor and the next issue I'm having is trying to bind dynamic data from a lookup table onto an InputSelect deal

Here's the Create Code:

@page "/movies/create"
@rendermode InteractiveServer
@using Microsoft.EntityFrameworkCore
@using BlazorWebAppMovies.Models
@using BlazorWebAppMovies.Data
@inject IDbContextFactory<BlazorWebAppMovies.Data.BlazorWebAppMoviesContext> DbFactory
@inject NavigationManager NavigationManager

<PageTitle>Create</PageTitle>

<h1>Create</h1>

<h2>Movie</h2>
<hr />
<div class="row">
    <div class="col-md-4">
        <EditForm method="post" Model="Movie" OnValidSubmit="AddMovie" FormName="create" Enhance>
            <DataAnnotationsValidator />
            <ValidationSummary class="text-danger" role="alert"/>
            <div class="mb-3">
                <label for="title" class="form-label">Title:</label> 
                <InputText id="title" @bind-Value="Movie.Title" class="form-control" /> 
                <ValidationMessage For="() => Movie.Title" class="text-danger" /> 
            </div>        
            <div class="mb-3">
                <label for="releasedate" class="form-label">Release Date:</label> 
                <InputDate id="releasedate" @bind-Value="Movie.ReleaseDate" class="form-control" /> 
                <ValidationMessage For="() => Movie.ReleaseDate" class="text-danger" /> 
            </div>        
            <div class="mb-3">
                <label for="genre" class="form-label">Genre:</label> 
                <InputText id="genre" @bind-Value="Movie.Genre" class="form-control" /> 
                <ValidationMessage For="() => Movie.Genre" class="text-danger" /> 
            </div>        
            <div class="mb-3">
                <label for="price" class="form-label">Price:</label> 
                <InputNumber id="price" @bind-Value="Movie.Price" class="form-control" /> 
                <ValidationMessage For="() => Movie.Price" class="text-danger" /> 
            </div>
            <div class="mb-3">
                <label for="rating" class="form-label">Rating:</label>
                <InputText id="rating" @bind-Value="Movie.Rating" class="form-control" />
                <ValidationMessage For="() => Movie.Rating" class="text-danger" />
            </div>
            <div class="mb-3">
                <label for="moviestarrating" class="form-label:">Movie Star Rating:</label>
                <InputSelect id="moviestarrating" @bind-value="Movie.MovieStarRatingId" class="form-control">
                    <option value="">-- Select --</option>
                    @foreach (var movieStarRating in StarRatings)
                    {
                        <option value="@movieStarRating.Id">@movieStarRating.Descr</option>
                    }
                </InputSelect>
                <ValidationMessage For="() => Movie.MovieStarRating" class="text-danger"></ValidationMessage>
            </div>
            <button type="submit" class="btn btn-primary">Create</button>
        </EditForm>
    </div>
</div>

<div>
    <a href="/movies">Back to List</a>
</div>

@code {
    private BlazorWebAppMoviesContext context = default!;

    [SupplyParameterFromForm]
    private Movie Movie { get; set; } = new();

    private IQueryable<MovieStarRating> StarRatings => context.MovieStarRating;

    // To protect from overposting attacks, see https://learn.microsoft.com/aspnet/core/blazor/forms/#mitigate-overposting-attacks.
    private async Task AddMovie()
    {
        using var context = DbFactory.CreateDbContext();
        context.Movie.Add(Movie);
        await context.SaveChangesAsync();
        NavigationManager.NavigateTo("/movies");
    }
}

It's throwing an "object reference not set to instance of object" or something like that saying that my context object is null. Again, I'm quite new to this.

1 Answer 1

0

There may be a couple of issues here, but you see how you're injecting a DbContextFactory at the top of the page? You haven't created a context from it, so the context is indeed null.

You are creating a context instance in your AddMovie function; you'll need to do the same thing before you can access it elsewhere.

I guess if it were me, I'd do something like this:

@code {
[SupplyParameterFromForm]
private Movie Movie { get; set; } = new();

private IList<MovieStarRating> StarRatings {get; set;} = [];

protected override async Task OnInitializedAsync() {
    await using var context = await DbFactory.CreateDbContextAsync();
    StarRatings = await context.MovieStarRating.ToListAsync();
}

It's not perfect, but I'm running with what you've got. Basically, if you are going to inject a context factory, you need to create a context instance from it. You could do this as above in OnInitializedAsync and populate a list with the movie ratings.

Sign up to request clarification or add additional context in comments.

1 Comment

Ah thank you for that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.