Developer forum

Forum » Development » Notificationsubscribers for DWAPI requests}

Notificationsubscribers for DWAPI requests}

Arnór Halldórsson
Arnór Halldórsson
Reply

Hi guys,

I wanna throw a slightly radioactive curveball at you :D

All of our projects are using the LiveIntegrationV1 or LSRetailIntegrationFramework and more and more our team is getting into scenarios where we'd like to edit the data returned from the dwapi requests, ideally without having to update the data in the database. For example when we're getting live prices for specific customers, I think we can all agree that updating the prices in the EcomPrices table is not a trivial task, specially if you're not familiar with the DW source code.

Nicolai mentioned to us a few weeks / days ago the possibility of creating an extension method of sorts that could return a custom model and that would override the pre-existing method, but if I remember correctly that would only work in DW 10.

What about notification subscribers for each dwapi request?

It's definetily more work for you guys to implement, but it could allow us to manipulate the ViewModels each request returns before the response is served without having to modify the data in the database. I could see this being implemented in two ways:

Scenario A: Each request would have a BeforeResponseIsReturned / AfterRequestIsProcessed subscriber that is triggered just before the return command in the controller method, after all internal DW logic is done and the ViewModel has been populated with data from Dynamicweb.

Scenario B: could be to have 2 subscribers per request:

  • BeforeRequestIsProcessed: Arguments could contain the input ViewModel (so we know what the hell is being asked for), the response ViewModel (empty ofc) and a boolean that cancels/skips all internal DW logic for that request so that the logic we write in the OnNotify override method would basicly be a new implementation for that request.
  • BeforeResponseIsReturned / AfterRequestIsProcessed: Arguments would probably only have to contain the response ViewModel. Allowing us to edit that data on the ViewModel to be returned from the DWAPI.

Changing the response ViewModel in either subscriber would affect the response returned from the DWAPI request, but ultimately if you implement the latter one then that's the data that you get.

What do you guys think? Should I be institutionalized or are we on to something here?

Best regards,
Arnór


Replies

 
Morten Snedker Dynamicweb Employee
Morten Snedker
Reply

I'm looking forward to a response from product owner. :-)

 

But I'm voting you out of the institution. ;)

/Snedker

 
Nicolai Pedersen
Reply
This post has been marked as an answer

It is a big wish and we are on it. I actually coded the below in the plane when visiting you a couple of weeks ago - it runs on my machine :-) !

Expect that you can do overrides of viewmodels instead - those modifications would work in webapi and viewmodel templates as well:

This is an 'advanced' scenario where you can do specialized overrides on item based content (Page, GridRow, Paragraph, maybe pageview).

The concept would be the same for i.e. productviewmodel and priceviewmodel - just wihtout the addinname attribute.

[AddInName("MultiPurposeParagraph")]
    public class SwiftPosterViewModel : ParagraphViewModel
    {
        private object _instance;
        public SwiftPosterViewModel()
        {
            //this is initialisation. The model does not have anyting set at this point.
            //Initialize objects, i.e. services, that can be used throughtout the instance - i.e. to get addtional data.
            _instance = new object();

            //This will not work as the header will be overriden later in the initialisation process of this object.
            base.Header = "Set header in constructor does not work";
        }

        /// <summary>
        /// Take over default property of the base viewmodel. Suitable to change default behavior
        /// </summary>
        public new string Header
        {
            get
            {
                return $"{base.Header} changed";
            }
        }

        /// <summary>
        /// Addtional data property available in template. Suitable for additional data
        /// </summary>
        public string NameOrTile
        {
            get
            {
                if (Item.GetRawValue("Title") is object)
                {
                    return Item.GetRawValue("Title").ToString();
                }
                else
                {
                    return Header;
                }
            }
        }

        /// <summary>
        /// Method to call from template using data from the model instance. Suitable for rendering logic
        /// </summary>
        /// <returns></returns>
        public string GetPosterPadding()
        {
            string posterPadding = Item.GetRawValueString("ContentPadding", string.Empty);
            string posterPaddingClass = string.Empty;

            switch (posterPadding)
            {
                case "none":
                    posterPaddingClass = " p-3 px-xl-3 py-xl-4";
                    break;
                case "small":
                    posterPaddingClass = " p-3 p-xl-4";
                    break;
                case "large":
                    posterPaddingClass = " p-4 p-xl-5";
                    break;
            }
            return posterPaddingClass;
        }
    }
Votes for this answer: 2
 
Arnór Halldórsson
Arnór Halldórsson
Reply

Hi Nic,

Sorry for the late reply, I had to track down my braincells after the easter holidays, still missing a few though...

Big wishes are the best cause they usually come with big rewards :D

A few follow up questions:

  1. I thought that this would only be possible in DW 10, are you intending on implementing this for DW9 as well?
  2. Would DW automatically grab the overridden view model or would we have to specify somehow when to use it?
  3. If we were to override the ProductViewModel with new custom fields for LivePrices or LiveStock or whatever else, would we be able to use those fields in the FilledProperties input paremeter of the /dwapi/ecommerce/products/ endpoint to control wether or not to activate the logic behind those fields?

Best regards,
Arnór

 
Nicolai Pedersen
Reply

Hi Arnor

@1: yes, this has been implemented and currently being released.

@2: yes, Dynamicweb will pick it up if it is there. In webapi you just add the overriden type - in razor you will also get the overriden type injected as the model in the razor template, and if you change your inherits statement, you will also get intellisense for it.

@3: Maybe - it requires that you fill the properties using a 'propertyfiller' thing that we use:

var propertyFiller = new ViewModelPropertyFiller<ProductViewModel>(settings.FilledProperties);
propertyFiller.Fill(model, nameof(model.VariantName), () => GetVariantName(product)); //lazy loaded property
propertyFiller.Eager(model, nameof(model.VariantId), product.VariantId); //eager loaded property

How to do that from an extension remains to be explored!

Viewmodels that can be extended in round 1:

  • AreaViewmodel
  • PageviewViewModel
  • PageInfoViewModel
  • ParagraphViewmodel
  • ParagraphInfoViewModel
  • GridRowViewModel
  • ProductListViewModel
  • ProductViewmodel
  • OrderViewmodel
  • OrderlineViewmodel
 
Arnór Halldórsson
Arnór Halldórsson
Reply

Awesome!! Simply awesome!

We expecting this to hit with the next release or?

 
Nicolai Pedersen
Reply

Dynamicweb.Ecommerce 1.13.44+ will contain this feature. For content item types it will be 9.13.18+

BR Nicolai

 
Casper Rasmussen
Casper Rasmussen
Reply

Would it also be posiple to extend the UserViewModel and ShippingViewModel Viewmodels ?

 

You must be logged in to post in the forum