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

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies