toJSON issue
Dear finnsson,
I got an issue while calling toJSON.
console.log( ko.toJSON( theViewModel ) );
pager.extendWithPage( theViewModel );
console.log( ko.toJSON( theViewModel ) );
The first executed perfectly
{"personal":{"sex":"male", ....
the second console logging fails:
TypeError: JSON.stringify cannot serialize cyclic structures.
How can I use the toJSON of knockout? What do I miss?
Thanks,
Imre
I've actually never tried to call ko.toJSON. The error is due to that a page keeps a reference to its parent page while the parent-page keeps a reference to its children (thus cyclic structures). I don't know if there is some way I can instruct ko.toJSON to skip some of these fields. I read at Controlling how an object is converted to JSON that I should probably implement pager.Page.prototype.toJSON. I haven't tried anything but a solution might be
pager.Page.prototype.toJSON = function() {
return this.ctx;
};
Wrote a simple test:
<!DOCTYPE html>
<html>
<head>
<script src="/js/lib/jquery-2.0.3.min.js"></script>
<script src="/js/lib/knockout-latest.js"></script>
<script src="/js/lib/pager.min.js"></script>
</head>
<body>
<script type="text/javascript">
function AppViewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
this.capitalizeLastName = function() {
var currentVal = this.lastName(); // Read the current value
this.lastName(currentVal.toUpperCase()); // Write back a modified value
};
}
var theViewModel = new AppViewModel();
console.log( ko.toJSON( theViewModel ) );
pager.extendWithPage( theViewModel );
console.log( ko.toJSON( theViewModel ) );
ko.applyBindings(new AppViewModel());
</script>
</body>
</html>
Jepp. It works in that case. I would recommend that you just add
pager.Page.prototype.toJSON = function() {
return this.ctx;
};
for now. I'll try to add and test it for the 1.1-release.
OK, thank you.
After executing this:
ko.applyBindings(theViewModel);
I receive this Error for toJSON:
Pass a function that returns the value of the ko.computed
By executing this:
theViewModel.toJSON = function() {
var copy = ko.toJS(this);
delete copy['$__page__'];
return copy;
};
The JSON export seems fine till the applyBindings. After it I receive that message. If I put the pager usage into comments, everything is fine.
Here is a complete very small sample what I'm dealing with, hope it helps:
<!DOCTYPE html>
<html>
<head>
<script src="/js/lib/jquery-2.0.3.min.js"></script>
<script src="/js/lib/knockout-latest.js"></script>
<script src="/js/lib/pager.min.js"></script>
</head>
<body>
<div data-bind="page: {id: 'ignite', title: 'Greetings', role: 'start'}">
Sportif: <input type="checkbox" data-bind="checked: personal.sportif" />
</div>
<script type="text/javascript">
$(document).ready(function(){
pager.Page.prototype.toJSON = function() {
return this.ctx;
};
function AppViewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
this.capitalizeLastName = function() {
var currentVal = this.lastName(); // Read the current value
this.lastName(currentVal.toUpperCase()); // Write back a modified value
};
this.personal = {
sportif: ko.observable( false )
};
}
var theViewModel = new AppViewModel();
console.log( '?', ko.toJSON( theViewModel ) );
pager.extendWithPage( theViewModel );
console.log( ':', ko.toJSON( theViewModel ) );
ko.applyBindings( theViewModel );
console.log( '-', ko.toJSON( theViewModel ) );
pager.start();
console.log( '*', ko.toJSON( theViewModel ) );
});
</script>
</body>
</html>
And a jsfiddle: http://jsfiddle.net/ndJsk/
Is there anything I can help?
The problem is, that after the pager starts, some elements will posses attributes like this:
selectionDirection: [Exception: Error] selectionEnd: [Exception: Error] selectionStart: [Exception: Error]
And here the knockoutJS will fail to generate the JS object so the JSON also. Without the pager, the input field in the test html won't have such exceptions.
Commenting out all pager-related code from temp.html and the input element does not have such attributes and knockout runs perfectly.
Just made a workaround solution: https://github.com/finnsson/pagerjs/pull/130 Maybe not the best solution but works perfectly for me.
Any chance that fix can get merged in and released? I love using ko.toJSON to watch stuff change, and it doesn't work with pager!