Copied to clipboard

Flag this post as spam?

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


  • Nigel Wilson 945 posts 2077 karma points
    Mar 02, 2013 @ 02:38
    Nigel Wilson
    0

    Get Distinct List of Child Nodes Based on Properties

    Hey there

    I have written some code which is almost working how I want it to, but am somewhat stumped onone smallpart.

    I have a page on my site with the ability to add a comment. I want to include a checkbox so that commentors can subscribe to receive an email notification when a new comment is posted.

    So I am trying to write some code to loop through all comments under the page and build a list of email addresses to send to.

    The comment node has the following properties - name (textbox), email (textbox), notify (true/false) and comment (textbox multiple).

    My code so far is as follows (triggered via the publish event on the comment document type)

     

    public class emailRecipient
        {
            public string name { get; set; }
            public int id { get; set; }
            public string email { get; set; }
        }
    public static void sendEmailsToCommentors(Document comment)
            {
                Node parent = new Node(comment.Parent.Id);
                List _commentNodes = parent.AllDescendants().Where(n => n.GetPropertyAsString("receiveNotifications") == "1").ToList();
                
                var distinctEmailNodes = (from loc in _commentNodes
                                      select new emailRecipient
                                      {
                                          email = loc.GetPropertyAsString("email"), 
                                          id = loc.Id, 
                                          name = loc.GetPropertyAsString("name")
                                      }
                                      ).Distinct();
    foreach (var n in distinctEmailNodes)
            { 
    //Send email code goes here
    }

     

    The above is working and sending emails, however it is not creating a distinct list, rather sending to all nodes where the "notify" property is set to true. Therefore if someone has commented more than once they will get multiple emails.

    Whislt I can appreciate why the Distinct() isn't working, I haven't been able to figure out a solution.

    Can anyone provide any suggestions? Also feel free to comment on if there is a better alternative way.

    I do appreciate there are packages for commenting, however wanted to have a play myself in order to provide a bit of personal development.

    Cheers, Nigel

     

     

     

  • Nigel Wilson 945 posts 2077 karma points
    Mar 02, 2013 @ 03:19
    Nigel Wilson
    100

    Ahh wouldn't ya know it - Google is my friend and i have created a solution immediately after posting my original question... 

    So I still have the following class

    public class emailRecipient
        {
            public string name { get; set; }
            public int id { get; set; }
            public string email { get; set; }
        }

    But the logic has changed as follows:

    public static void sendCommentorNotifications(Document comment)
            {
                Node parent = new Node(comment.Parent.Id);
                var emailNodes = (from loc in parent.AllDescendants() 
                                  select new emailRecipient
                                  {
                                      email = loc.GetPropertyAsString("email"),
                                      id = loc.Id,
                                      name = loc.GetPropertyAsString("name")
                                  }
                                      );

                var distinctItems = emailNodes.Distinct(new DistinctItemComparer());

                foreach (var n in distinctItems)
                {
                    //Send email logic
                }
            }

    And then as a separate class I have an equality comparer (this bit was the missing piece of the puzzle)

    class DistinctItemComparer : IEqualityComparer
        {
            public bool Equals(emailRecipient x, emailRecipient y)
            {
                return x.email == y.email;
            }
            public int GetHashCode(emailRecipient obj)
            {
                return obj.email.GetHashCode();
            }
        }

    Upward and onward

    Nigel

  • Hendy Racher 863 posts 3849 karma points MVP 2x admin c-trib
    Mar 02, 2013 @ 10:54
    Hendy Racher
    0

    Hi Nigel,

    Just tried the following (in a razor script) in v6, and this seems to work too:

    foreach(Node comment in uQuery.GetNodesByType("Comment")
                                  .Where(node => node.GetProperty<bool>("recieveNotificiations"))
                                  .DistinctBy(node => node.GetProperty<string>("email")))
    {
        @(comment.GetProperty<string>("email"))
    }
    

     The .DistictBy() method is in the Umbraco.Core.EnumerableExtensions (but not sure in which version of Umbraco this was added).

    Hendy

Please Sign in or register to post replies

Write your reply to:

Draft