hotdiggity
hotdiggity

Reputation: 329

Update KnockoutJS viewModel using mapping and localStorage to maintain persistence

I need the data saved to localStorage, "savedData", to update the currently empty view model when the page is revisted/refreshed, possibly using the KO mapping plug-in in the line:

ko.mapping.fromJS(this, retrievedData);

But of course it's not working!

function viewModel() {

    var self = this;

    self.employees = ko.observableArray([]);

    self.removeEmployee = function (employee) {
        self.employees.remove(employee);
    };

    self.addEmployee = function () {
        self.employees.push(new Employee());
    };

    self.save = function () {
        var savedData = ko.toJSON(this);
        localStorage.setItem('savedData', savedData);
        //console.log('savedData', JSON.parse(savedData))
    }

    if (localStorage && localStorage.getItem('savedData')) {
        var retrievedData = JSON.parse(localStorage.getItem('savedData'));
        ko.mapping.fromJS(this, retrievedData);
    }
}

var vm = new viewModel();
ko.applyBindings(vm);

Upvotes: 1

Views: 545

Answers (1)

Anatolii Gabuza
Anatolii Gabuza

Reputation: 6260

Problem is in fromJS parameters. Second parameter is mapping options but you are trying to pass data instead. Proper usage should be following

var viewModel = ko.mapping.fromJS(retrievedData, mappingOptions);

If you don't want map retreivedData to viewModel using mappingOptions

ko.mapping.fromJS(retrievedData, {}, viewModel);

This will convert your data to viewModel without any specific mapping options.


NOTE: If you call mapping.fromJS with two arguments and second argument IS mapping object (__ko_mapping__ property defined) it will treat second argument as a viewModel and you can use function in a different manner:

ko.mapping.fromJS(retrievedData, viewModel);

Basically this scenario is valid when you are not creating viewModel, but instead updating previously created using mapping viewModel with some data.


ANSWER: You should update your code co map properly by passing empty options parameter. An of course data should go first:

if (localStorage && localStorage.getItem('savedData')) {
    var retrievedData = JSON.parse(localStorage.getItem('savedData'));
    ko.mapping.fromJS(retrievedData, {}, self);
}

Upvotes: 1

Related Questions