Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Jimmy 31 posts 147 karma points
    Apr 20, 2019 @ 09:05
    Jimmy
    0

    Need help to avoid loop in loop

    Hi

    I would love to get some help to optimize my code.

    I have 2 document types. Speaker and Session.

    The Session documentype have among other properties a "Speakers" property, which is a multiple Treepicker.

    In my Speaker template, I want to list all sessions that a speaker is in.

    Currently I use this code, and it works, but it seems like bad performance to to through all sessions in a loop, and then another loop to check which sessions a speaker is in.

    var selection = Umbraco.Content(Guid.Parse("fb14808c-7e8c-404c-9c07-af8e7b92622c"))   // all sessions
    .Children()
    .Where(x => x.IsVisible());
    
    foreach (var item in selection) // loop all sessions
    {
        var selection2 = item.Value<IEnumerable<IPublishedElement>>("speakers"); // all speakers in that session
            if(selection2 != null) {
                foreach (var session2 in selection2)
                {
    
                   if(@session2.Value("pageTitle")==Model.Value("pageTitle")) { // write out if the speaker is in this sessions. 
                <li><a href="@item.Url">@item.Name</a></li>
                   }
    
    
                }
            }       
    }
    
  • Søren Gregersen 441 posts 1884 karma points MVP 2x c-trib
    Apr 21, 2019 @ 12:34
    Søren Gregersen
    1

    Hi,

    As I understand it, you have a Speaker and a Session. Session has a list of speakers.

    To get all the sessions that a speakers is in, could then be done with:

    put this a the top of you view, before any of the html

    @{
    
    // get all sessions as a list to avoid multiple iterations...
    var allSessions = Umbraco.Content(Guid.Parse("fb14808c-7e8c-404c-9c07-af8e7b92622c"))
        .Children()
        .Where(x => x.IsVisible())
        .ToList();
    
    // get sessions for a speaker
    var speakerSessions = allSessions
       .Where(x=>{
         //select the speakers and check if the match the current speaker (model)         
         var speakers = x.Value<IEnumerable<IPublishedElement>>("speakers");
         return speakers != null && speakers.Any(s=>s.ID=Model.ID)
       })
       .ToList();
    }
    

    put this in the body of the view, where needed

    @foreach(var session in speakerSessions){
        <li><a href="@session.Url">@session.Name</a></li>
    }
    

    I don't recommend you use the "pageTitle" as a way to match if the documents are the same.

  • Jimmy 31 posts 147 karma points
    Apr 21, 2019 @ 14:57
    Jimmy
    0

    Hi Søren

    Thank you so much, this was exactly what I was looking for!

    One small issue, not sure why I get this error But in

    return speakers != null && speakers.Any(s=>s.ID=Model.ID);
    

    I get an error.

    CS1061: 'IPublishedElement' does not contain a definition for 'ID' and no accessible extension method 'ID' accepting a first argument of type 'IPublishedElement' could be found (are you missing a using directive or an assembly reference?)
    

    So right now I changed it to

    return speakers != null && speakers.Any(s=>s.Value("pageTitle").ToString()==Model.Value("pageTitle").ToString());
    

    But you are right, it would be much better with ID, but I just can't get it to work.

    The top of my template looks like this

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<Speaker>
    
    @using ContentModels = Umbraco.Web.PublishedModels;
    
  • Søren Gregersen 441 posts 1884 karma points MVP 2x c-trib
    Apr 21, 2019 @ 18:23
    Søren Gregersen
    100

    Hi,

    I just copied your code, and did’nt see that you read the speakers as IPublishedElement, but it should be IPublishedContent.

    var speakerSessions = allSessions
        .Where(x=>{
       //select the speakers and check if the match the current speaker (model)         
       var speakers = x.Value<IEnumerable<IPublishedContent>>("speakers");
         return speakers != null && speakers.Any(s=>s.ID==Model.ID)
     }).ToList();
    
  • Jimmy 31 posts 147 karma points
    Apr 22, 2019 @ 07:20
    Jimmy
    1

    Hi Søren

    Ohh, should have seen that myself :-)

    You have been a great help, thank you so much.

    Best regards

    Jimmy

Please Sign in or register to post replies

Write your reply to:

Draft