Question

in my checkout page when promo code is applied, I am updating a text using some calculation using knockoutjs

In my checkout page, on applying and removing promo code, it changes the discount key in totals.totals().items. How to apply bindings and subscribe in knockoutjs, so that I can call my function which I am calling from my HTML.

Magento_Checkout/web/template/summary/item/details.html

 <span class="tag-text">
    <!-- ko if: getFinalSale($parent)-->
      <u class="product-tag underline-bold-text checkout-final-sale" data-bind="text: getFinalSale($parent)"></u>
    <!-- /ko -->
</span>

I have written above code in details.html

and my js is

Magento_Checkout/web/js/view/summary/item/details.js

knockout js

  define([
   'uiComponent',
   'ko',
   'Magento_Checkout/js/model/totals'
    ], function (Component, ko, totals) {
   'use strict';
    var finalSaleData = window.checkoutConfig.items;

    return Component.extend({
     defaults: {
         template: 'Magento_Checkout/summary/item/details'
     },
    quoteItemData: quoteItemData,
    finalSaleData: finalSaleData,

    /**
     * @param {Object} quoteItem
     * @return {String}
     */

    getItems: function(item_id) {
        var itemElement = null;
        _.each(this.finalSaleData, function(element, index) {
            if (element.item_id == item_id) {
                itemElement = element;
            }
        });
        return itemElement;
    },
    getFinalSale : function (quoteItem) {
        var item = this.getItems(quoteItem.item_id);
        var temp_item = this.getTempItems(quoteItem.item_id);
        var tagText = '';

        if((((temp_item.price*temp_item.qty) - temp_item.discount_amount)/(item.base_old_price*temp_item.qty)) < 0.5){
            var tagText = 'Final Sale';
        }else{
            if(item.base_old_price && temp_item.price){
                // && item.price < item.price && item.base_old_price / item.price <= 0.5){
                if(((item.base_old_price - temp_item.price)/item.base_old_price)>0.5){
                    var tagText = 'Final Sale';
                }
            }
        }
        return tagText;
    }, 
  });
});

I am using var finalSaleData = window.checkoutConfig.items in my function getFinalSale.

How to make getFinalSale function run every time when window.checkoutConfig.items data is changed without refreshing the page.

1) How can i call getFinalSale on the change of totals.totals().items

2) The issue I am passing the $parent from my HTML and when the totals.totals().items the discount amount is changed for each item after applying promo code then how will I pass this $parent(quoteItem) from the very same js.

How to solve that.

The problem is, this runs only when the page reloads.

How to make getFinalSale function run every time the user applies promo code without refreshing the page so that my HTML gets updated too.

Basically Final Sale text needs to be shown on the basis of that logic in js code in getFinalSale function.

And also, data-bind="text: getFinalSale($parent) i am calling this from HTML and I am using subscribe also but then how i will pass $parent parameter from subscribing so that getFinalSale runs when this.totals changes everytime after applying coupon.

initialize: function(){
        this._super();
        this.totals.subscribe(function (data) {
          this.getFinalSale(data)
        }, this);
    } ,

The data parameter is not same as $parent which i passed it from html. and it breaks the js.

Was it helpful?

Solution

So the solution was simple, To make getFinalSale function run every time data of price/discount changes

Use totals: quote.getTotals()

   return Component.extend({
    defaults: {
        template: 'Magento_Checkout/summary/item/details'
    },
    quoteItemData: quoteItemData,
    finalSaleData: finalSaleData,
    saleData: saleData,
    totals: quote.getTotals(),
    /**
     * @param {Object} quoteItem
     * @return {String}
     */


    getFinalSale : function (quoteItem) {
        var tagText = '';
        var price = 0;
        if(this.totals()) {
                var item = null;
                _.each(this.finalSaleData , function(element, index) {
                    if (element.item_id == quoteItem.item_id) {
                        item = element;
                    }
                });

                var temp_item = null;
                _.each(this.totals().items, function(element, index) {
                    if (element.item_id == quoteItem.item_id) {
                        temp_item = element;
                    }
                });

                var discount = this.getDiscountPureValue(quoteItem.item_id);

                if ((((temp_item.price * temp_item.qty) - discount) / (item.base_old_price * temp_item.qty)) < 0.5) {
                    price = totals.getSegment('grand_total').value;
                } else {
                    if (item.base_old_price && temp_item.price) {
                        if (((item.base_old_price - temp_item.price) / item.base_old_price) > 0.5) {
                            price = totals.getSegment('grand_total').value
                        }
                    }
                }
        }
        return price;
    },
});

and also to get the updated discount value always

Use this.totals() instead of this.totals which was the mistake, I was doing.

 getDiscountPureValue: function (id) {
        var price = 0;
        var item = null;
        if (this.totals() && this.totals().items){
            _.each(this.totals().items , function(element, index) {
                if (element.item_id == id) {
                    item = element;
                }
            });
            price = item.discount_amount;
        }

        return price;
    },

OTHER TIPS

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top