Copied to clipboard

Flag this post as spam?

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


  • Richard Terris 273 posts 715 karma points
    Jan 24, 2013 @ 14:23
    Richard Terris
    0

    DynamicNode.Next() breaking at nodes with no children

    Looking for some help guys:

    I'm trying to do a very simple navigation on a page, with next and previous buttons.

    The tree structure consists of 2 document types "Service" and "Case Study", the former is the category and the latter is the child.

    In order to access the Next() function these have to be of DynamicNode type, but as some categories have no children it's falling over.

    I managed to get round this by checking for null, if(@Model.Next() != null) and if it IS null, moving up() and then next() - this works fine until I get to a stage where I have 2 empty parents in a row. Tried various operations moving up and down the tree but stuck.

    Where I'm at now is having a DynamicNodeList containing only documents of type "CaseStudy" and trying to iterate over that - as this should avoid meeting any parent nodes.

    This allows me to show on the page, the names of all the nodes in the list:

    DynamicNode startNode = new DynamicNode(1066);
        DynamicNodeList convertedList = startNode.DescendantsOrSelf("CaseStudy");
        <span>Case studies all together as one list, without service pages in between:</span>
        <ul>
        @foreach (DynamicNode item in convertedList)
        {
         <li>@item.Name</li>   
        }
        </ul>

    But for some reason when I try to include next it's failing:

    foreach(DynamicNode node in convertedList)
        {
            <a href="@node.Next().Url">NEXT</a>
        }

    Getting the error: Object reference not set to an instance of an object.

    Where am I going wrong?

  • Bert Loedeman 10 posts 30 karma points
    Jan 24, 2013 @ 14:48
    Bert Loedeman
    0

    Hi,

    First of all: which Umbraco version are you using?

    If I understand what you are doing, next should go to the next available child. When there is no next item, the result of Next() will be NULL. This is correct behaviour. The NRE you get most probably comes from NULL.Url (NULL being the Next() call returning NULL in some cases). Checking for NULL is the correct option. You should only call the Url property when the result is not NULL.

    When you go up to the content's parent to find next items to link to, you should keep on doing so until a) you find a parent giving another result to @node.Next() than NULL  or b) you find out you are on the root without getting any further (e.g. there is nothing more to go to).

    Hope this helps! Otherwise, please clarify ;) ...

    Cheers, Bert

  • Richard Terris 273 posts 715 karma points
    Jan 24, 2013 @ 14:53
    Richard Terris
    0

    Umbraco 4.9.1

    I understand I would get null if I was traversing through Model.Children but I'm looping through a list of DynamicNode elements consisting of only nodetypealias "CaseStudy" so I wouldn't expect any nulls at least until I get to the end of the list

    Does that make sense?

  • Richard Terris 273 posts 715 karma points
    Jan 24, 2013 @ 15:06
    Richard Terris
    0

    also tried:

    @foreach (DynamicNode item in convertedList)

        {

            Node currentNode = umbraco.NodeFactory.Node.GetCurrent();

            if (currentNode.Id == item.Id)

            {

                DynamicNode myNode = new DynamicNode(currentNode.Id);

                <li><a href="@myNode.Next().Url">NEXT</a></li>

            }

     

        }

     

    This is all because I'm trying to avoid tons of nested if statements to check that "next" is not null.

    This could also get quite messy if the structure of the tree changes because I'd need to test the logic again

  • Richard Terris 273 posts 715 karma points
    Jan 25, 2013 @ 09:01
    Richard Terris
    0

    Hey Dan, this is what I currently have:

    @{ 

        Node startNode = new Node(Convert.ToInt32(ConfigurationManager.AppSettings["CaseStudies"]));

        ListconvertedList = ContentHelper.GetChildrenByAlias(startNode.Id, true, "CaseStudy");

        Case studies all together as one list, without service pages in between:

       

        @foreach (var item in convertedList)

        {

            Node currentNode = umbraco.NodeFactory.Node.GetCurrent();

            if (currentNode.Id == item.Id)

            {

                DynamicNode myNode = new DynamicNode(currentNode.Id);

                if(@myNode.Next() != null)

                {

               

     

            }

            }

        }

       

    }

    I even filtered the list with a LINQ expression .Items.Take(1) but still the same.

    It's giving me the next url but only until it reaches the end of that branch of the tree which would then leave me having to move up and then next.

    It seems as if my list is being ignored and it's defaulting to Model.Children, but I'm not using @Model anywhere in the script so very strange indeed.

  • Dan Patching 31 posts 158 karma points c-trib
    Jan 25, 2013 @ 10:21
    Dan Patching
    100

    Hi Richard,

    Rather than doing this ...

    umbraco.NodeFactory.Node.GetCurrent()

    You can use the "Model" object in razor, which is the current node the page represents.

    So to get all CaseStudies, I would use the code below. (Alias's are probably not right for your project).

    @{ var caseStudies = Model.AncestorOrSelf("RootNode").Descendants("CaseStudies"); }
    @foreach(var c in caseStudies)
    {
        if(c.Next() != null)
        {
            <a title="" href="@c.Next().NiceUrl">Next</a>
        }
    }
    

    I haven't tested this, but it should work fine.

    Hope that helps.

    EDIT: Made a correction to the razor in the 'if' statement.

  • Richard Terris 273 posts 715 karma points
    Jan 25, 2013 @ 11:06
    Richard Terris
    0

    Actually this hasn't worked.

    I click on the first case study and I get a 15 links to the next item in the list (as there are 15 case studies inside the foreach)

    When I click through the link to the next I get Cannot perform runtime binding on a null reference

    This is because we're using @Model

    If I use @caseStudy.Next I get 15 links to 15 different case studies and if I filter the list to Take(1) I get nothing

  • Richard Terris 273 posts 715 karma points
    Jan 25, 2013 @ 13:42
    Richard Terris
    0

    Caught a lucky break here.

    The details of the project changed meaning I had to restructure the document types, so now the case studies do not have parent category nodes.

    The solution by Dan has fixed the problem now that the new structure is in place

Please Sign in or register to post replies

Write your reply to:

Draft