Rian Mostert Rian Mostert - 1 month ago 18
TypeScript Question

Typescript & Knockout.js Math.max computed

I'm trying to create a dynamic steps system for a website I'm working on.

It should display current step out of total steps and change current and/or total steps depending on conditions.

e.g.

Step 1/2

Step 2/2

Unfortunately I'm running into a problem I'm not sure how to diagnose because I don't know why it's giving me the error.

The error is:
"Uncaught TypeError: Cannot read property 'StepNumberOne' of undefined"

Here's my code:



class ViewModel {
public IsStepOneActive: KnockoutObservable < boolean > ;
public IsStepTwoActive: KnockoutObservable < boolean > ;

public StepNumberOne: KnockoutComputed < number > ;
public StepNumberTwo: KnockoutComputed < number > ;

public Total: KnockoutComputed < number > ;

constructor() {
this.IsStepOneActive = ko.observable(true);
this.IsStepTwoActive = ko.observable(false);

this.StepNumberOne = ko.pureComputed(function() {
if (this.IsStepOneActive()) {
return 1;
} else {
return 0;
}
});

this.StepNumberTwo = ko.pureComputed(function() {
if (this.IsStepTwoActive()) {
return 2;
} else {
return 0;
}
});

this.Total = ko.computed(function() {
return Math.max(this.StepNumberOne(), this.StepNumberTwo);
});
}
}

ko.applyBindings(new ViewModel());

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="target">
<div>
<span data-bind="text: StepNumberOne"></span>
<span> / </span>
<span data-bind="text: Total"></span>
</div>

<div>
<span data-bind="text: StepNumberTwo"></span>
<span> / </span>
<span data-bind="text: Total"></span>
</div>
</div>




Answer

You should use data-bind attribute insetead of data-binding

Additionally you need to change:

ko.computed(() => {
  return Math.max(this.StepNumberOne(), this.StepNumberTwo);
});

You need to have the delegate there because the scope will be different there

Comments