Parker3306
Parker3306

Reputation: 63

KnockoutJS computed is undefined

I have a computed observable of two integer based observables that I'm trying to turn into a timespan value. It seems like it should be pretty easy by looking at documentation but I am getting an undefined:undefined value from my computed. Apologies if this is hard to follow. Any help is much appreciated. Here is my JS:

var Routine = function (routine_name, minutes, seconds, duration, rest, rounds) {
    this.routine_name = ko.protectedObservable(routine_name);
    this.minutes = ko.protectedObservable(minutes);
    this.seconds = ko.protectedObservable(seconds);
    //this.duration = ko.protectedObservable(duration);
    this.rest = ko.protectedObservable(rest);
    this.rounds = ko.protectedObservable(rounds || 1);

    this.duration = ko.computed(function () {
        return this.minutes + ':' + this.seconds;
    });

} 

var RoutineModel = function (Routines) {

    var self = this;
    self.routine_id = ko.observable();
    self.routine_name = ko.observable();
    //self.duration = ko.observable();
    self.minutes = ko.observable();
    self.seconds = ko.observable();
    self.rest = ko.observable();
    self.rounds = ko.observable();
    self.workout_name = ko.observable();

    self.duration = ko.computed(function () {
        return self.minutes() + ':' + self.seconds();
    });

this.Routines = ko.observableArray(Routines);

this.selectedRoutine = ko.observable();

this.addRoutine = function () {

            var newRoutine = new Routine("new routine", 0, 0, 0, 0);
            self.Routines.push(newRoutine);
            self.selectedRoutine(newRoutine);

    };

this.acceptRoutineEdit = function () {
        var selectedRoutine = self.selectedRoutine();
        selectedRoutine.routine_name.commit();
        selectedRoutine.minutes.commit();
        selectedRoutine.seconds.commit();
        //selectedRoutine.duration.commit();
        selectedRoutine.rest.commit();
        selectedRoutine.rounds.commit();
        self.selectedRoutine(null);

        selectedRoutine.duration = ko.computed(function () {
            return selectedRoutine.minutes + ':' + selectedRoutine.seconds;
        });
    };
};

Upvotes: 0

Views: 568

Answers (1)

RP Niemeyer
RP Niemeyer

Reputation: 114792

Your duration computed is using this and is being calculated with the wrong context.

When you define a computed, you can pass in a second argument to control the value of this when your computed is evaluated like:

   this.duration = ko.computed(function () {
        return this.minutes() + ':' + this.seconds();
    }, this);

Your other computeds, don't use this, so don't seem to have the same issue.

Additionally, in this computed and in selectedRoutine.duration computed, make sure that you call observables as functions to retrieve their value like:

return selectedRoutine.minutes() + ':' + selectedRoutine.seconds();

Upvotes: 1

Related Questions