0

I run a small Magento store and would like to extend my Checkout with some functionality. Magento uses KnockoutJS and I want to extend a KnockoutJS component with a simple function that returns either true or false depending on the response of an AJAX call:

isEnabled: function () {
    var result = false;
    $.getJSON('/mycontroller/checkEnabled', function(response) {
        // response from the controller is simply "true" or "false", in this case "true"
        result = response
    })
    return result
}

Unfortunately this always returns false, even if the response of the getJSON is "true". It's because of the AJAX call being asynchronous I think and the return result being executed immediately instead of waiting for the AJAX to complete.

I have already googled how to solve this and tried a myriad of different solutions over the past hours, async / await, promises, callbacks (from here), but I just don't understand how to get the response value back into my isEnabled function after the AJAX call is finished.

This is really making my head hurt, as I only have experience with synchronous programming languages so far.

How do I make the isEnabled simply return the boolean value from the getJSON AJAX call?

Chad3000
  • 91
  • 1
  • 3

1 Answers1

0

I would separate the two.

  1. have an isEnabled property that represents the current state
  2. and a function that retrieves the necessary data from the server to determine the Enabled state and sets the isEnabled observable when the promise is returned.

something like this.

function ViewModel() {
  var self = this;
  self.isEnabled = ko.observable(false);
  self.checkIfEnabled = function() {
    //To simulate getting data from a server
    setTimeout(function() {
      //promise has returned, so set the value of enabled.
      self.isEnabled(!self.isEnabled());
    }, 1000);
  }
}

ko.applyBindings(new ViewModel());
.is-enabled {
  background-color: #FFFF00;
  color: #000000;
}

.is-not-enabled {
  background-color: #000000;
  color: #FFFF00;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<button data-bind="click: checkIfEnabled">Check State</button>

<div data-bind="css:{'is-enabled': isEnabled, 'is-not-enabled': !isEnabled() }">This should change color.  Current State: <span data-bind="if: isEnabled">Enabled</span><span data-bind="ifnot: isEnabled">Disabled</span></div>
Nathan Fisher
  • 7,961
  • 3
  • 47
  • 68