Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save Knockout observableArray JSON to localStorage

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();
like image 629
Matt Gibson Avatar asked Oct 02 '22 11:10

Matt Gibson


1 Answers

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/

like image 164
pax162 Avatar answered Oct 13 '22 10:10

pax162