Copied to clipboard

Flag this post as spam?

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


  • Ayo Adesina 419 posts 1001 karma points
    Jan 17, 2020 @ 15:44
    Ayo Adesina
    0

    Umbraco Events - getting newly created node inside the ContentService.Saved event

    This is the first time I'm using Umbraco events in Umbraco 8.

    I have subscribed to the ContentService.Saved event and this is firing correctly.

    However when a new node is created when I try to use the umbraco helper to retrive it as IPublished content, but I always get null. Why is this?

    As I understand it this event fires AFTER the new node has been saved, so I don't understand why I get NULL.

    Here is my code, any ideas?

    public class SubscribeToSaveEventComposer : ComponentComposer<SubscribeToSaveEventComponent>
    { }
    
    public class SubscribeToSaveEventComponent : IComponent
    {
        public void Initialize()
        {
            ContentService.Saved += ContentService_Saved;
            ContentService.Saving += ContentService_Saving;
        }
    
        private void ContentService_Saved(IContentService sender, ContentSavedEventArgs e)
        {
            foreach (var node in e.SavedEntities)
            {
                if (node.ContentType.Alias == "clientContainer")
                {   
                     //Why is Brand New Node = NULL
                    var brandNewNode = Umbraco.Web.Composing.Current.UmbracoHelper.Content(node.Id);
    
                   .........
                }
            }
        }
    
  • Malthe Petersen 64 posts 357 karma points c-trib
    Jan 17, 2020 @ 16:00
    Malthe Petersen
    0

    Hi.

    It is because you try to get something from the cache, which is not yet there.

    If you want that, you have to listen to CacheRefreserBase

  • Ayo Adesina 419 posts 1001 karma points
    Jan 17, 2020 @ 16:08
    Ayo Adesina
    0

    when you mean listen to CacheRefreserBase what do you mean? I googled that and actually got 0 results lol

  • Malthe Petersen 64 posts 357 karma points c-trib
    Jan 17, 2020 @ 16:28
    Malthe Petersen
    0

    It is not yet documented,

    Instead if ContentService.Saving/Saved you have to listen to CacheRefresherBase<ContentCacheRefresher>.CacheUpdated and now you should be able to get the newly created node from the cache.

    You can also just use save events, but then you need to get the data from the ContentService and that data will come from the database. You can do that by doing Current.Services.ContentService. And it will be of type IContent instead of IPublishedContent.

  • Ayo Adesina 419 posts 1001 karma points
    Jan 17, 2020 @ 16:41
    Ayo Adesina
    0

    OK that makes sense, I just tried to do this:

    CacheRefresherBase<ContentCacheRefresher>.CacheUpdated += ContentService_Saved; 
    

    but its not compling

    No overload for 'ContentService_Saved' matches delegate 'TypedEventHandler

    So I'm guessing there is a little more to it, can I have a code sample please?

  • Malthe Petersen 64 posts 357 karma points c-trib
    Jan 17, 2020 @ 16:46
    Malthe Petersen
    102

    Sorry I was on my IPad. Here is an example. It is because the arguments is different from the ones you have in your saved method:

       public void Initialize()
        {
            CacheRefresherBase<ContentCacheRefresher>.CacheUpdated += CacheUpdated;
        }
    
        private void CacheUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs e)
        {
                var payloads = e.MessageObject as ContentCacheRefresher.JsonPayload[];
                if (payloads == null)
                {
                    return;
                }
           ...
           ...
        }
    

    The payload needs to be casted to the correct type. :-)

  • Malthe Petersen 64 posts 357 karma points c-trib
    Jan 21, 2020 @ 16:20
    Malthe Petersen
    1

    Did you get it to work? :-)

  • Ayo Adesina 419 posts 1001 karma points
    Jan 21, 2020 @ 19:51
    Ayo Adesina
    0

    yes :-) Thank you!

  • Nik 1401 posts 6161 karma points MVP 3x c-trib
    Jan 21, 2020 @ 18:52
    Nik
    1

    Hi Ayo,

    A bit more of an explanation as to why you aren't getting results from the cache.

    When you save a content node it doesn't update the cache, instead it updates the underlying database which is accessible via the content service. The Umbraco cache only contains published content, so unless the content was also published (in which case you will want to subscribe to the Published event) you'll either get nothing, or you'll get outdated content.

    The published content is stored in the Umbraco Cache to make the frontend faster.

    Another thing to be aware of, this isn't the best way to access the Umbraco Cache when you in an event like this. This is because it is possible that an Umbraco Context is missing, instead I'd recommend taking advantage of the built in dependency inject and having a constructor paramter on your Component of type IUmbracoContextFactory. This will have a method called "EnsureUmbracoContext" which returns a UmbracoContextReference on which you can call UmbracoContext and this has a get method to get you IPublishedContent based on an ID.

    Hope that makes a bit of sense and explains why it's not working the way you are expecting.

    Nik

  • Petras Surna 81 posts 131 karma points
    Jan 25, 2021 @ 00:13
    Petras Surna
    0

    Unfortunately, the CacheUpdated event is not fired when saving a Member only when saving Content

    public void Initialize()
    {
      CacheRefresherBase<ContentCacheRefresher>.CacheUpdated += CacheUpdated;
    }
    
    private void CacheUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs e)
    {
    }
    

    Is there a separate Member Cache Updated event? Or is it possible to read Member properties direct from the database? Reading from the database is fine but I don't know how to do it.

  • Malthe Petersen 64 posts 357 karma points c-trib
    Jan 25, 2021 @ 06:55
    Malthe Petersen
    1

    Hi Petras!

    You should be able to do something like:

    CacheRefresherBase<MemberCacheRefresher>.CacheUpdated += CacheUpdated;
    
    private void CacheUpdated(MemberCacheRefresher sender, CacheRefresherEventArgs e)
    {
       ...
    }
    
  • Petras Surna 81 posts 131 karma points
    Jan 25, 2021 @ 08:00
    Petras Surna
    0

    Incredible, that works! Thank you so much.

  • Malthe Petersen 64 posts 357 karma points c-trib
    Jan 25, 2021 @ 08:11
    Malthe Petersen
    0

    Perfect! Happy to help.

  • Petras Surna 81 posts 131 karma points
    Jan 25, 2021 @ 11:07
    Petras Surna
    0

    I am still having problems doing what I need which is to read the value of a ContentPicker in a Member after it is saved for the first time.

    I notice that

      CacheRefresherBase<MemberCacheRefresher>.CacheUpdated += CacheUpdated;
    

    Is called before

      MemberService.Saved += MemeberService_Saved;
    

    But I can't get the Member details I need in either case when saving a new member.

    However, when saving an existing member I can get what I need.

    My code to access the ContentPicker is:

      var helper = Umbraco.Web.Composing.Current.UmbracoHelper;
      var member = (Umbraco.Web.PublishedModels.Member)helper.Member(payload.Id);
      var organisation = (Umbraco.Web.PublishedModels.Organisation)member.Organisation;
      firstName = member.FirstName;
    

    The organisation has a value when saving an existing Member but not when saving a new Member

    Perhaps the value is in the database when one of the events is called and I can read it from there? Not sure how to do that.

Please Sign in or register to post replies

Write your reply to:

Draft