locked
If else condition in MVC view RRS feed

  • Question

  • User-501297529 posted

    I'm trying to loop thru if else condition where if they are current show the item and if not show the message that there are no items. The problem i am having is the message keeps showing no matter what. What am I doing incorrectly? Here is the code

     <div class="col-md-6">
            <ul>
                @foreach (var item in Model.Items)
                {
                    if (item.IsCurrent == true)
                    {
                        <li>
                            @item.Id
                        </li>
                    }
                    else if (item.IsCurrent == false)
                    { 
                        @: There is not a current Item at this time. Do you want to
                        <a asp-area="Admin" asp-controller="Item" asp-action="CreateItem"> add a Item?</a>
                    }
                }
    
    
                
    
            </ul>
            
        </div>

    Wednesday, July 17, 2019 4:25 PM

Answers

  • User475983607 posted

    bootzilla

    I don't think this will work because the if item.Any line is outside of the foreach and it won't recognize item.Any as a local variable and the 'Add a Item?' message is also out of the loop and doesn't recognize the @ symbol before it.

    It's the idea not the syntax.   I suspect the code you shared does not meet the actual requirement.

    An example that display the id 3.

            [HttpGet]
            public IActionResult Index()
            {
                //Populate the model
                List<Item> _mockList = new List<Item>()
                {
                     new Item() { ItemId = 3, IsCurrent = true },
                     new Item() { ItemId = 4, IsDraft = true },
                     new Item() { ItemId = 7, IsCurrent = false },
                     new Item() { ItemId = 8, IsArchived = true },
    
                }; 
                return View(_mockList);
            }
    @model List<MvcApi22.Models.Item>
    @{
        ViewData["Title"] = "Index";
    }
    
    
    <h1>Index</h1>
    
    <div>
        @if (Model.Any(i => i.IsCurrent))
        {
            <ul>
                @foreach (var item in Model)
                {
                    if (item.IsCurrent)
                    {
                        <li>
                            @item.ItemId
                        </li>
                    }
                }
            </ul>
        }
        else
        {
            <div>
                <a href="#">Add an Item?</a>
            </div>
        }
    </div>

    There are several issue with mock and the code shown.  I hope the actual type is not static as that would be very bad.  The Mock Id is ItemId not Id as shown in the View.  There are three Boolean properties in the Item class.  

        public class Item
        {
            public int ItemId { get; set; }
            public bool IsCurrent { get; set; }
            public bool IsDraft { get; set; }
            public bool IsArchived { get; set; }
        }

    You should use an enumeration which ends up being one field rather than three you have to manage.

        public enum Status
        {
            Current,
            Draft,
            Archived
        }
    
        public class Item2
        {
            public int ItemId { get; set; }
            public Status Status { get; set; }
        }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, July 17, 2019 9:02 PM
  • User475983607 posted

    On the view when I call Model.Items I get 'Non-invocable member cannot be used like a method mvc view'

     @if ((Model.Items(i => i.IsCurrent)))

    The Any() extension is missing.

    @if (Model.Items.Any(i => i.IsCurrent))

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, July 18, 2019 2:05 PM

All replies

  • User475983607 posted

    I'm trying to loop thru if else condition where if they are current show the item and if not show the message that there are no items. The problem i am having is the message keeps showing no matter what. What am I doing incorrectly? Here is the code

     <div class="col-md-6">
            <ul>
                @foreach (var item in Model.Items)
                {
                    if (item.IsCurrent == true)
                    {
                        <li>
                            @item.Id
                        </li>
                    }
                    else if (item.IsCurrent == false)
                    { 
                        @: There is not a current Item at this time. Do you want to
                        <a asp-area="Admin" asp-controller="Item" asp-action="CreateItem"> add a Item?</a>
                    }
                }
    
    
                
    
            </ul>
            
        </div>

    The symptom indicates that item.IsCurrent is always false.  Have you tried running the code through the debugger to verify the items in the loop are expected?

    Secondly, refactor the code to make it more concise. 

    @foreach (var item in Model.Items)
    {
    	if (item.IsCurrent)
    	{
    		<li>
    			@item.Id
    		</li>
    	}
    	else
    	{ 
    		@: There is not a current Item at this time. Do you want to
    		<a asp-area="Admin" asp-controller="Item" asp-action="CreateItem"> add a Item?</a>
    	}
    }
    

    Wednesday, July 17, 2019 6:38 PM
  • User-501297529 posted

    bootzilla

    I'm trying to loop thru if else condition where if they are current show the item and if not show the message that there are no items. The problem i am having is the message keeps showing no matter what. What am I doing incorrectly? Here is the code

     <div class="col-md-6">
            <ul>
                @foreach (var item in Model.Items)
                {
                    if (item.IsCurrent == true)
                    {
                        <li>
                            @item.Id
                        </li>
                    }
                    else if (item.IsCurrent == false)
                    { 
                        @: There is not a current Item at this time. Do you want to
                        <a asp-area="Admin" asp-controller="Item" asp-action="CreateItem"> add a Item?</a>
                    }
                }
    
    
                
    
            </ul>
            
        </div>

    The symptom indicates that item.IsCurrent is always false.  Have you tried running the code through the debugger to verify the items in the loop are expected?

    Secondly, refactor the code to make it more concise. 

    @foreach (var item in Model.Items)
    {
    	if (item.IsCurrent)
    	{
    		<li>
    			@item.Id
    		</li>
    	}
    	else
    	{ 
    		@: There is not a current Item at this time. Do you want to
    		<a asp-area="Admin" asp-controller="Item" asp-action="CreateItem"> add a Item?</a>
    	}
    }

    When I debug thru the code it hits both conditions. It find the current item and then go back thru the loop and it hits the false condition when I want it to skip that if there are current items.

    Wednesday, July 17, 2019 7:39 PM
  • User-821857111 posted

    The debugger will always stop on the if(item.IsCurrent). If that condition returns false, it will stop at else. As was stated previously, IsCurrent is always false. Hover over it in the debugger or look in the locals window when debugging to confirm.

    Your challenge is to work out why it is always false. 

    Wednesday, July 17, 2019 7:50 PM
  • User-501297529 posted

    The debugger will always stop on the if(item.IsCurrent). If that condition returns false, it will stop at else. As was stated previously, IsCurrent is always false. Hover over it in the debugger or look in the locals window when debugging to confirm.

    Your challenge is to work out why it is always false. 

    I've tried this and don't know why. None of the records are showing as false. One record shows as true. The message shouldn't show/shouldn't go into the else condition at all.

    Wednesday, July 17, 2019 8:11 PM
  • User-821857111 posted

    Since we cannot see the code where the IsCurrent property is set, we can only comment on your description of what happens. 

    Wednesday, July 17, 2019 8:22 PM
  • User475983607 posted

    bootzilla

    I've tried this and don't know why. None of the records are showing as false. One record shows as true. The message shouldn't show/shouldn't go into the else condition at all.

    Maybe your requirement does not match the shared code.   

    If any record has a true IsCurrent property, then show all the IsCurrent items.  Otherwise show the "Add an Item" button.

    if(item.Any(i => i.IsCurrent)) 
    {
    	@foreach (var item in Model.Items)
    	{
    		if (item.IsCurrent)
    		{
    			<li>
    				@item.Id
    			</li>
    		}
    	}
    } else
    {
    	@: There is not a current Item at this time. Do you want to
    	<a asp-area="Admin" asp-controller="Item" asp-action="CreateItem"> add a Item?</a>
    }



    Wednesday, July 17, 2019 8:28 PM
  • User-501297529 posted

    Since we cannot see the code where the IsCurrent property is set, we can only comment on your description of what happens. 

    here is the property:

    public bool IsCurrent { get; set; }

    Here is mock in the service:

    private static List<Item> _mockList = new List<Item>()
            {
                 new Item() { ItemId = 3, IsCurrent = true },
                 new Item() { ItemId = 4, IsDraft = true },
                 new Item() { ItemId = 7, IsCurrent = false },
                 new Item() { ItemId = 8, IsArchived = true },
                 
            }; 

    Hopefully this helps in what you need to see.

    Wednesday, July 17, 2019 8:32 PM
  • User-501297529 posted

    bootzilla

    I've tried this and don't know why. None of the records are showing as false. One record shows as true. The message shouldn't show/shouldn't go into the else condition at all.

    Maybe your requirement does not match the shared code.   

    If any record has a true IsCurrent property, then show all the IsCurrent items.  Otherwise show the "Add an Item" button.

    if(item.Any(i => i.IsCurrent)) 
    {
    	@foreach (var item in Model.Items)
    	{
    		if (item.IsCurrent)
    		{
    			<li>
    				@item.Id
    			</li>
    		}
    	}
    }
    {
    	@: There is not a current Item at this time. Do you want to
    	<a asp-area="Admin" asp-controller="Item" asp-action="CreateItem"> add a Item?</a>
    }



    I don't think this will work because the if item.Any line is outside of the foreach and it won't recognize item.Any as a local variable and the 'Add a Item?' message is also out of the loop and doesn't recognize the @ symbol before it.

    Wednesday, July 17, 2019 8:54 PM
  • User-821857111 posted

    Based on that, I would expect to see one list item, and three messages with links. The messages and links will be rendered inside a <ul>, which isn't valid. I don't know how that will appear on screen, but you can check the HTML by viewing the source code. 

    Wednesday, July 17, 2019 8:57 PM
  • User475983607 posted

    bootzilla

    I don't think this will work because the if item.Any line is outside of the foreach and it won't recognize item.Any as a local variable and the 'Add a Item?' message is also out of the loop and doesn't recognize the @ symbol before it.

    It's the idea not the syntax.   I suspect the code you shared does not meet the actual requirement.

    An example that display the id 3.

            [HttpGet]
            public IActionResult Index()
            {
                //Populate the model
                List<Item> _mockList = new List<Item>()
                {
                     new Item() { ItemId = 3, IsCurrent = true },
                     new Item() { ItemId = 4, IsDraft = true },
                     new Item() { ItemId = 7, IsCurrent = false },
                     new Item() { ItemId = 8, IsArchived = true },
    
                }; 
                return View(_mockList);
            }
    @model List<MvcApi22.Models.Item>
    @{
        ViewData["Title"] = "Index";
    }
    
    
    <h1>Index</h1>
    
    <div>
        @if (Model.Any(i => i.IsCurrent))
        {
            <ul>
                @foreach (var item in Model)
                {
                    if (item.IsCurrent)
                    {
                        <li>
                            @item.ItemId
                        </li>
                    }
                }
            </ul>
        }
        else
        {
            <div>
                <a href="#">Add an Item?</a>
            </div>
        }
    </div>

    There are several issue with mock and the code shown.  I hope the actual type is not static as that would be very bad.  The Mock Id is ItemId not Id as shown in the View.  There are three Boolean properties in the Item class.  

        public class Item
        {
            public int ItemId { get; set; }
            public bool IsCurrent { get; set; }
            public bool IsDraft { get; set; }
            public bool IsArchived { get; set; }
        }

    You should use an enumeration which ends up being one field rather than three you have to manage.

        public enum Status
        {
            Current,
            Draft,
            Archived
        }
    
        public class Item2
        {
            public int ItemId { get; set; }
            public Status Status { get; set; }
        }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, July 17, 2019 9:02 PM
  • User711641945 posted

    Hi bootzilla,

    1.As mgebhard said, your mock id is ItemId but your view shows id. Is it our misunderstanding of your model definition?Could you share the whole model?

    The problem i am having is the message keeps showing no matter what.

    Do you mean that you get four messages but one record is true and others are false ?

    2.By testing your code and mgebhard 's code, it get the following two result. Which result is your requirement:

    • Result by your code (one record is true and others are false):

    • Result by mgebhard(if only it has one record with IsCurrent=true, it would not show the message):

     

    Best Regards,

    Rena

    Thursday, July 18, 2019 3:04 AM
  • User-501297529 posted

    Here is the model:

     public class ItemIndexViewModel
        {
            public IEnumerable<Item> Items { get; set; } 
            
            public Item SelectedItem { get; set; }
    
            public IEnumerable<Item> DraftItems { get; set; }
    
    
            
        }

    On the view when I call Model.Items I get 'Non-invocable member cannot be used like a method mvc view'

     @if ((Model.Items(i => i.IsCurrent)))
            {
                <ul>
                    @foreach (var Item in Model.Items)
                    {
                        if (Item.IsCurrent)
                        {
                            <li>
                                @Item.ItemId
                            </li>
                        }
                    }
                </ul>
            }
            else
            {
                <div>
                    There is not a current item at this time. Do you want to <a asp-area="Admin" asp-controller="Item" asp-action="CreateItem"> add a Item?</a>
                </div>
            }

    Thursday, July 18, 2019 1:40 PM
  • User475983607 posted

    On the view when I call Model.Items I get 'Non-invocable member cannot be used like a method mvc view'

     @if ((Model.Items(i => i.IsCurrent)))

    The Any() extension is missing.

    @if (Model.Items.Any(i => i.IsCurrent))

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, July 18, 2019 2:05 PM
  • User-501297529 posted

    mgebhard

    bootzilla

    On the view when I call Model.Items I get 'Non-invocable member cannot be used like a method mvc view'

     @if ((Model.Items(i => i.IsCurrent)))

    The Any() extension is missing.

    @if (Model.Items.Any(i => i.IsCurrent))

    Thanks mg. We've had our disagreements at times but you are still very helpful. I appreciate it. Don't think I don't.

    Thursday, July 18, 2019 2:13 PM