Why can I not return a Null Value?

38 views Asked by At

I am creating an app where users can keep inventory of purchased food items. As new users create their pantry, they have the option of creating new ingredients OR adding ingredients that other users have previously submitted (i.e. no need to create a new ingredient called Chicken Breast if another user already has this in their pantry).

On my view page, I have a form where users can select already added ingredients to add to their own pantry. Right now, I am able to display ALL of the ingredients in the data base with no problems, and add these ingredients to the current user's pantry.

I am trying to add a search/filter feature that allows users to search what ingredients are already in the database. This prevents them from having to scroll through hundreds of items to find exactly what they're looking to add, or determine if they must create this ingredient as no other user has the ingredient in their database.

View (newIngredients.cshtml)

@model AddIngredientsView

@{
    ViewBag.Title = "Pantry Setup";
    ViewBag.HeaderText = "Add Your First Set of Ingredients To Your Pantry";
    Layout = "~/Views/Home/_Layout.cshtml";
}

<div class="formBox">
    <form asp-action="CreateIngredients" asp-contoller="Home" method="post">
        <h3>Existing Ingredients</h3>
        @using (Html.BeginForm("NewIngredients", "Home", FormMethod.Get))
        {
            @Html.TextBox("searching")<input type="submit" value="Search">
        }
        @for(int i =0; i < Model.AllIngredients.Count; i++){
            @Html.HiddenFor(m => m.AllIngredients[i].id);
            <label asp-for="IsAddedIngredient[i]">@Model.AllIngredients[i].Name</label>
            <input type="checkbox" asp-for="IsAddedIngredient[i]">

            <label asp-for="AddIngredientsQuantity[i]">Quantity</label>
            <input type="number" step="0.01" asp-for="AddIngredientsQuantity[i]">
            <br>
        }
</div>

View Model (AddIngredientsView.cs)

using System.Collections.Generic;

namespace ThisProject.Models{
    public class AddIngredientsView{
        public Merchant Merchant{get;set;}

        public List<Ingredient> AllIngredients{get;set;}

        public List<string> AddIngredientsQuantity{get;set;}
        public List<bool> IsAddedIngredient{get;set;}
        public List<Ingredient> NewIngredients{get;set;}
        public List<double> NewIngredientsQuantity{get;set;}
        public List<Pantry> PantryItems{get;set;}
    }
}

HomeController:

[HttpGet("ingredients/new")]
        public IActionResult NewIngredients(string searching){
            AddIngredientsView viewModel = new AddIngredientsView();
            viewModel.Merchant = context.Merchants.FirstOrDefault(m => m.id == merchantId);
            viewModel.AllIngredients = context.Ingredients.ToList();

            return View("newIngredients", viewModel.AllIngredients.Where(x => x.Name.Contains(searching) || searching == null).ToList());
        }

The expected result would be a list of all ingredients initially. When a user searches for the ingredient in the @Html.TextBox("searching") it filters all of the items that do not match their request.

I have ten ingredients that are in the database and are called properly when I omit the code between @using (Html.BeginForm....){} in the View Page, and simply return View("newIngredients") in the Home Controller.

The code compiles when submitted as written, but does not render in the browser. I receive the following error when the page is rendered:

An unhandled exception occurred while processing the request. ArgumentNullException: Value cannot be null. Parameter name: value

string.IndexOf(string value, int startIndex, int count, StringComparison comparisonType) ArgumentNullException: Value cannot be null. Parameter name: value

string.IndexOf(string value, int startIndex, int count, StringComparison comparisonType)
string.Contains(string value)
ThisProject.Controllers.HomeController+<>c__DisplayClass7_0.<NewIngredients>b__1(Ingredient x) in HomeController.cs

            return View("newIngredients", viewModel.AllIngredients.Where(x => x.Name.Contains(searching) || searching == null).ToList());

System.Linq.Enumerable+WhereListIterator.ToList() System.Linq.Enumerable.ToList(IEnumerable source) ThisProject.Controllers.HomeController.NewIngredients(string searching) in HomeController.cs

            return View("newIngredients", viewModel.AllIngredients.Where(x => x.Name.Contains(searching) || searching == null).ToList());
1

There are 1 answers

0
dmkrebsbach On

I solved the problem, I was passing in viewModel incorrectly.

The Conroller works when changing the last two lines to the following:

[HttpGet("ingredients/new")]
        public IActionResult NewIngredients(string searching){
            AddIngredientsView viewModel = new AddIngredientsView();
            viewModel.Merchant = context.Merchants.FirstOrDefault(m => m.id == merchantId);
            viewModel.AllIngredients = context.Ingredients.Where(x => x.Name.Contains(searching) || searching==null).ToList();

            return View("newIngredients", viewModel);
        }

Thank you.