1

I am trying to edit an existing payment method module template:

This is a looped object option (which is information about the current loop iteration payment method).

The original template loop:

<ul class="types">
    <!-- ko foreach: { data: JSON.parse(getPaymentTypesList()), as: 'option' } -->
    <li class="option-type" onclick="jQuery(this).find('input[name=payment-type]').prop('checked', true);">
        <input class="paygate-payment-type" data-bind="attr: {'value': option.value}" name="payment-type"
            type="radio" />
        <label class="label">
            <span class="payment-type-label">
                <!-- ko i18n: option.label -->
                <!-- /ko -->
            </span>
            <span class="payment-type-label-img">
                <img alt="" class="payment-type-label-img" data-bind="attr: {'src': option.image}" />
            </span>
        </label>

    </li>
    <!-- /ko -->
</ul>   

I want to use parameters to a custom function I created in the .js knockout object file; using the option payment method provided in the template already, see sample visible bind to the option.

<p class="payment-type-extra-description" data-bind="visible: isPaymentMethod(option, 'BT')">
    <span class="payment-type-extra-description-span">- I just want to show this specific paragraph using 'visible' when the option object is the specified 'payment method' value.</span>
</p>
    isPaymentMethod: function (methodValue, paymentMethod) {
        if (paymentMethod && methodValue) {
          return paymentMethod == methodValue.value
        }
        return false
    },

I think I have two issues here which relate to this question, but without both resolved I can't solve the problem.

  • I don't know how to provide arguments in the loop (using option)
  • isPaymentMethod is not defined, but only when inside the loop; if I call the isPaymentMethod on an element outside the loop; this function is called without error (but I don't have arguments available since it is not inside the loop)

Error supplied in console; but as pointed out only when inside the loop

Uncaught ReferenceError: Unable to process binding "if: function(){return (paymentTypesEnabled() != 0) }"
Message: Unable to process binding "foreach: function(){return { data:JSON.parse(getPaymentTypesList()),as:'option'} }"
Message: Unable to process binding "visible: function(){return isPaymentMethod() }"
Message: isPaymentMethod is not defined
  • How do I provide parameters to a function inside the loop?
  • How do I get the loop to 'recognize' the isPaymentMethod function; because outside the loop the visible: isPaymentMethod() is called (but have not provided arguments).

1 Answer 1

1

After being completely confused about the issue this morning, I tried to research about the context of the knockout objects, as it appeared to me I need to find out why the function didn't work inside the loop.

I then found the _Binding Context_ article and this relevant information:

$parent

This is the view model object in the parent context, the one immeditely outside the current context. In the root context, this is undefined


$parentContext

This refers to the binding context object at the parent level. This is different from $parent, which refers to the data (not binding context) at the parent level.

Only after reading $parentContext and then $parent I understood the context better.

The function implementation was already correct, so all I needed was to figure out how to call the function from the parent context:

<p class="payment-type-extra-description" data-bind="visible: isPaymentMethod(option, 'BT')">

should become

<p class="payment-type-extra-description" data-bind="visible: $parent.isPaymentMethod(option, 'BT')">

For a long time I thought that the parameters I gave caused the isPaymentMethod function signature not to be 'recognized' by Knockout in the loop, wasting time on trying to solve the wrong issue (figuring out 'syntax' for option as argument).

Only after investigating the context (binding context in knockout) is when I realised the issue is easy to resolve.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.