adamlj
adamlj

Reputation: 225

ko.observable Not updating in Durandal/KO/breeze

I am new to Durandal/breeze/knockout and am attempting to use them in a project, but I have gotten stuck early on.

Currently I have a single view (#/household/new) to create a new household. I have fetched the breeze metadata from the api and then run EntityManager.createEntity('Household'), this returns a household object as I would expect.

I then set value of the StreetAddress property and update the ko.observable (vm.household(hse)). Once the view displays the observable is not working. My view model at the moment is really simple, a text input, and a div. They both have data-binds to the StreetAddress property, but neither of them update nor start with the default value that I set.

Oddly enough I am not getting any errors along the way to help me get closer to a solution. I really don't know where I am going wrong. Any help would be excellent. Below is the code that I am trying to use.

New Household View

<div>
    <h3>New Household Details</h3>
    <div data-bind="text: household.StreetAddress"></div>
    <input type="text" data-bind="value: household.StreetAddress" />
</div>

New Household Viewmodel:

define(function (require) {
    var router = require('durandal/plugins/router');
    var mainDataservice = require('dataservices/mainDataservice');
    var system = require('durandal/system');

    var vm = {
        router: router,
        activate: activate,
        household: ko.observable()
    };    
    return vm;

    function activate() {
        return system.defer(function (dfd) {
            var hse = mainDataservice.createHousehold();
            hse.StreetAddress("1234 Main Street");
            vm.household(hse);            
            dfd.resolve();
        }).promise();
    }
});

MainDataservice

define(function (require) {

    var serviceName = 'api/mainDataservice', // route to the Web Api controller
        manager = new breeze.EntityManager(serviceName);

    return {
        manager: manager,
        activate: function () {
            //I call this manually at the start of the application
            return manager.fetchMetadata();
        },

        createHousehold: function () {
            return manager.createEntity('Household');
        }
    };
});

Household Entity Framework Model

public partial class Household
{    
    [Key]
    [Required]
    [Display(Name = "Household ID")]
    public int HouseholdID { get; set; }

    [StringLength(50)]
    [Display(Name = "Street Address")]
    public string StreetAddress { get; set; }

    [StringLength(50)]
    [Display(Name = "City")]
    public string City { get; set; }

    [StringLength(2)]
    [Display(Name = "State")]
    public string State { get; set; }

    [StringLength(10)]
    [Display(Name = "Zipcode")]
    public string Zipcode { get; set; }
}

Upvotes: 1

Views: 1449

Answers (1)

nemesv
nemesv

Reputation: 139758

Because household is an observable (which is a function) you need to use it like a function (i.e. you need to put out the ()) when you want to get its value inside an expression:

<div>
    <h3>New Household Details</h3>
    <div data-bind="text: household().StreetAddress"></div>
    <input type="text" data-bind="value: household().StreetAddress" />
</div>

Note1: you don't need the () after StreetAddress because KO can unwrap automatically the last property of the expression.

Not2: you don't get an error because household exists so it is valid to call household.StreetAddress which just returns undefined so you won't see anything on the UI

Upvotes: 2

Related Questions