1

In my typescript file, I am trying to have an observable class which holds all my UI related fields, which I can then get and post to the server. I have it outisde of my viewmodel, as I want to separate the fields I post, to all the other view model items.

So, in my typescript file, first off, I create my UI model.

interface Model {
    id: KnockoutObservable<number>;
}


class MyViewModel {

    model: KnockoutObservable<Model>;

    constructor() {

    $.get("/api/debt/1")
        .done((data) => {
            this.model().id(data.ID);
        }); 
    }

}

This doesn't work. For some reason, 'this.model' is unknown.

Is what I am trying to do even possible? What am I doing wrong?

Edit: Simplified to just use the id property. Using interface, instead of class. Failing on this.model().id(data.ID), as 'mode is not a function). Not sure how to initialise the model now.

1 Answer 1

3

You've defined what model should be, its an object of type "KnockoutObservable", but you haven't actually created anything to fill the variable with so its value is still undefined.

Try replacing model: KnockoutObservable<Model>; with

model: KnockoutObservable<Model> = ko.observable(new Model());

EDIT 1:

Additionally you'll want to change your assignments below that to address the properties of the unboxed model instead of the observable itself by adding parenthesis:

    this.model().id = ko.observable(0);
    this.model().description = ko.observable("");
    this.model().openingBalance = ko.observable(0);
    this.model().standardRate = ko.observable(0);

EDIT 2:

Typescript will preserve the context of "this" if you use a lambda expression for your callback instead of a standard function declaration.

$.get("/api/debt/1")
        .done((data) => {
             this.model().id(data.ID);
        }); 

You probably also want to assign the new value to the existing instance of your "id" observable rather than replacing the observable. Knockout's dependency tracking doesn't work if you overwrite the observables that its bound to. So you use the observable like a function instead of using an assignment operator (=).

EDIT 3:

Here's a more complete example:

class Model {
    id: KnockoutObservable<number>;
}


class MyViewModel {

    model: KnockoutObservable<Model> = ko.observable(new Model());

    constructor() {

      this.model().id = ko.observable(0);

      $.get("/api/debt/1")
        .done((data) => {
            this.model().id(data.ID);
        }); 
    }

}
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks for that! In my .done, after I do the get, is that the right way to assign? I've made the changes you said, but on the assignment, it tells me that "TypeError: this.model is not a function". Additionally, shoud 'model' be observable? I want the properties to be observable. Maybe this is an error as well?
I think the problem down there might be that "this" doesn't refer to the class anymore and instead refers to the .done callback function. Javascript is weird that way. If you change your .done function into a lambda expression instead then typescript will automatically carry over the "this" context.
Updated my answer with an example of the lambda. Let me know if any of that needs more explanation.
Thanks @JasonSpake... getting closer, but still not working. I have changed the 'class Model' into 'interface Model' as that might be more correct. Then define the model instance as "model: KnockoutObservable<Model>;"... and then in my .done, I am trying to assign values like this "this.model().id(data.ID);". I changed tht function to lambda. But still get " this.model is not a function' when trying to assign id.
At this point your code is diverging a bit from what was originally posted. Can you edit your question with an updated paste of what you have?
|

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.