I am trying to save an observableArray using the ko.toJSON method to localStorage. On first page load, my app is going to receive a JSON object from the server and populate the observableArray. I'd like to store it in localStorage for optimization and offline use, but the ko.toJSON is returning [] even though there's clearly data in it.
I am able to reproduce this issue at this jsFiddle
HTML
<span data-bind="text: locations().length"></span>
<div data-bind="foreach: locations">
<div>
<span data-bind="text: title"></span>
<span> </span>
<span data-bind="text: timeZone"></span>
</div>
</div>
<pre data-bind="text: output"></pre>
JavaScript
var dataFromServer = [
{name: "Cleveland", zone: "EST"},
{name: "Chicago", zone: "CST"},
{name: "New York", zone: "EST"}
];
var MyNS = window.MyNS || {};
MyNS.ViewModel = function () {
var self = this;
self.locations = ko.observableArray([]);
self.load = function (){
var mappedData = ko.utils.arrayMap(dataFromServer, function(item) {
return new MyNS.Location(item.name, item.zone);
});
self.locations(mappedData);
};
self.output = ko.toJSON(self.locations());
self.execute = function(){
self.load();
ko.applyBindings(self);
};
};
MyNS.Location = function (t, z) {
this.title = t;
this.timeZone = z;
};
var model = new MyNS.ViewModel();
model.execute();
The problem is that the output
variable has its value written only once, at the first run of the constructor, when the locations array is empty. To update the output on locations change, you can turn it into a computed observable, like this:
self.output = ko.computed(function(){
return ko.toJSON(self.locations())
});
The updated fiddle: http://jsfiddle.net/wvgRL/4/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With