jgrewal
jgrewal

Reputation: 342

passing a Dictionary<string, List<model>> model to a view

Unclear on how to pass this model to my view. I have a list model being passed into my view. But I want to separate the Participant's inside the list depending on which User is logged in on the ViewBag.

current view code (working): this code works as it should but its not separating the participants depending on what user is logged in. it displays the entire list. I'm getting red squilies under @model, League inside my foreach line, and MMLeagueParticipants in my secondforeach. But it still worked.

error:

when I hovered over @model and League: The type or namespace name 'League' could not be found (are you missing a using directive or an assembly reference?)[LeagueProect]

When I hovered over MMLeagueParticipant: The type or namespace name 'MMLeagueParticpant' could not be found (are you missing a using directive or an assembly reference?`


//RED SQUIGLY #1 @model
@model List<League>
    @{    
        if (Model != null && Model.Any())
        {
            //RED SQUIGLY #2 League
            foreach(League i in Model)
            {
                //RED SQUIGLY #3 MMLeagueParticipant
                foreach (MMLeagueParticipant mmLeagueParticipant in i.allParticipants)
                {
                    <p>@mmLeagueParticipant.child.ParticipantFirstName @mmLeagueParticipant.child.ParticipantLastName</p>
                }  
            }
        }
        else
        {
            <p>the list is empty</p>
        }
    }

Attempt to separate (not working) still using @model List<League>. When I change my code to try and separate it crashes entirely

    <p>Your kid(s):</p>    
    if (Model != null && Model.Any())
    {
        foreach(League i in Model)
        {
            var userParticipants = i.allParticipants.Where(p => p?.child?.Parent?.UserId == ViewBag.UserId).ToList();
            foreach (MMLeagueParticipant mmLeagueParticipant in userParticipants)
            {
                <p>@mmLeagueParticipant.child.ParticipantFirstName @mmLeagueParticipant.child.ParticipantLastName</p>
            }  
        }
    }
    <p>not your kid(s):</p>
    if (Model != null && Model.Any())
    {
        foreach(League i in Model)
        {
            var userParticipants = i.allParticipants.Where(p => p?.child?.Parent?.UserId != ViewBag.UserId).ToList();
            foreach (MMLeagueParticipant mmLeagueParticipant in userParticipants)
            {
                <p>@mmLeagueParticipant.child.ParticipantFirstName @mmLeagueParticipant.child.ParticipantLastName</p>
            }  
        }
    }

The error I get from trying this:

NullReferenceException: Object reference not set to an instance of an object.

It doesn't like the lines:

I'm assuming the way I'm passing in the model to my view is incorrect. But entirely unsure why one way is working and the other isn't.

Controller details:

The tabs were working as needed when showing all Participants with my Current view code (as showed above) with their own list of different age groups when I wasn't sperating the participants depending on if they belong to the logged on user or not.

each tab in my RosterPageBasketballcontains the following code: @await Html.PartialAsync("_Displayeach", Model["bbM#and#"])

where I thought the issue might be: ("_Displayeach", Model["bbM7and8"])

the model I'm sending to my partial is Model["bbM7and8"] but the model I'm using in my _Displayeach is @model List<League>. unsure how or if it's possible to pass in @model Dictionary<string, List<League>>.


controller:

public async Task<IActionResult> GetBasketballRoster()
{
    String[] leagueNames = new[]
    {
        "bbM7and8",
        "bbM9and10",
        "bbM11and12",
        "bbM13and14",
        "bbM15and16",
        "bbM17and18",
        "bbF7and8",
        "bbF9and10",
        "bbF11and12",
        "bbF13and14",
        "bbF15and16",
        "bbF17and18"
    };
        Dictionary<string, List<League>> d = new Dictionary<string, List<League>>();
        foreach (var name in leagueNames)
        {
            List<League> bbLeagues = await db.Leagues
            .Where(l => l.sport == "Basketball")
            .Where(l => l.ageRange==name)
            .ToListAsync();

            foreach (League league in bbLeagues)
            {
                List<MMLeagueParticipant> leagueParticipants = await db.Entry(league)
                    .Collection(l => l.allParticipants)
                    .Query() // <-- This is needed to allow for `Include()`
                    .Include(mmp => mmp.child)
                    .ToListAsync();
            }
            d.Add(name,bbLeagues);
        }
        return View("RosterPageBasketball", d);
}

Upvotes: 1

Views: 799

Answers (1)

Rena
Rena

Reputation: 36595

From your code, it seems you want to display List<League> which is in partial view for specific ageRange.

Here is a working demo you could follow:

Model:

public class League
{
    public string sport { get; set; }
    public string ageRange { get; set; }
    public List<MMLeagueParticipant> allParticipants { get; set; }
}
public class MMLeagueParticipant
{
    public child child { get; set; }
}
public class child
{
    public string ParticipantFirstName { get; set; }
    public string ParticipantLastName { get; set; }
}

RosterPageBasketball.cshtml:

@model Dictionary<string, List<League>>

@{ 
    var data = Model.Where(a => a.Key == "bbF17and18").Select(a => a.Value).FirstOrDefault();
}
@await Html.PartialAsync("_Displayeach", data)

_Displayeach.cshtml:

@model List<League>
@{
    if (Model != null && Model.Any())
    {
        foreach (League i in Model)
        {
            foreach (MMLeagueParticipant mmLeagueParticipant in i.allParticipants)
            {
                <p>@mmLeagueParticipant.child.ParticipantFirstName @mmLeagueParticipant.child.ParticipantLastName</p>
            }
        }
    }
    else
    {
        <p>the list is empty</p>
    }
}

Controller:

public async Task<IActionResult> Index()
{
    String[] leagueNames = new[]
    {
        "bbM7and8",
        "bbM9and10",
        "bbM11and12",
        "bbM13and14",
        "bbM15and16",
        "bbM17and18",
        "bbF7and8",
        "bbF9and10",
        "bbF11and12",
        "bbF13and14",
        "bbF15and16",
        "bbF17and18"
    };
    Dictionary<string, List<League>> d = new Dictionary<string, List<League>>();
    foreach (var name in leagueNames)
    {
        //hard coded the data....
        List<League> bbLeagues = new List<League>()
        {
            new League(){sport="Basketball",ageRange="bbF17and18",allParticipants =new List<MMLeagueParticipant>(){ new MMLeagueParticipant() { child= new child() {ParticipantFirstName="San",ParticipantLastName="Da" } } } },
            new League(){sport="Basketball",ageRange="bbF17and18",allParticipants =new List<MMLeagueParticipant>(){ new MMLeagueParticipant() { child= new child() {ParticipantFirstName="Api",ParticipantLastName="Ee" } } }},
            new League(){sport="Basketball",ageRange="bbF9and10",allParticipants =new List<MMLeagueParticipant>(){ new MMLeagueParticipant() { child= new child() {ParticipantFirstName="May",ParticipantLastName="Fa" } } }},
            new League(){sport="Basketball",ageRange="bbM17and18",allParticipants =new List<MMLeagueParticipant>(){ new MMLeagueParticipant() { child= new child() {ParticipantFirstName="Ben",ParticipantLastName="He" } } }},
            new League(){sport="Basketball",ageRange="bbF15and16",allParticipants =new List<MMLeagueParticipant>(){ new MMLeagueParticipant() { child= new child() {ParticipantFirstName="Jun",ParticipantLastName="Pa" } } }},
            new League(){sport="FootBall",ageRange="bbF15and16",allParticipants =new List<MMLeagueParticipant>(){ new MMLeagueParticipant() { child= new child() {ParticipantFirstName="Pen",ParticipantLastName="Me" } } }}
        };

        var data = bbLeagues.Where(l => l.sport == "Basketball").Where(l => l.ageRange == name).ToList();
        d.Add(name, data);
    }
    return View("Index", d);
}

Upvotes: 1

Related Questions