# Revert knockout model original state back on update cancel?

I am using knockout in my project. I have some models like EmployeeModel, ServiceModel etc which user can update. On UI I give the user a Cancel control button by which he can revert the changes. On cancel I have to revert the model change back to its original state. For this I found these two good approaches by @rniemeyer:

Protected Observable

I can't use protected observables because I am using ko.mapping plugin which will create a knockout models base on server side viewmodels. Yes, I can use mapping option like Create, but I feel its not a good to keep separate observables state. I want solution which will be reusable and can apply to whole model.

And guess what I got, second good approach by same author @rniemeyer:

Simple editor pattern

I can't use this also because of the same reason I mentioned above. So I wrote 2 functions copy and reset which will do the job for me:

Copy

Here, source is the object whose current state we want to preserve, and dest keeps the current state.

function copy(source, dest) {

for (var key in source) {

if (source.hasOwnProperty(key)) {

//no need to keep knockout added properties
if (key === "__ko_mapping__")
continue;

//recursive call to copy if property is an object
else if (typeof source[key] === "object") {
dest[key] = {};
copy(source[key], dest[key]);
}

else {
//no need to copy the computed observable value
if (!ko.isComputed(source[key])) {
var value = ko.utils.unwrapObservable(source[key]);
dest[key] = value;
}
}
}
}

//remove all function
for (var key in dest) {
if (typeof dest[key] === "function")
delete dest[key];
}
}


Reset

Here, source is the previous dest and dest is the previous source.

function reset(source, dest) {

for (var key in source) {

if (source.hasOwnProperty(key)) {

//recursive call to copy if it is an object
if (source[key] !== null && typeof source[key] === "object") {
reset(source[key], dest[key]);
}

else {
if (ko.isObservable(dest[key]))
dest[key](source[key]);
else
dest[key] = source[key];
}
}
}
}


I want you to please review these function and let me know if these function require any improvement.

• You declare var key twice in copy, that is not required
• You are not using hasOwnProperty(key) when you delete all the functions in copy
• You could have merged source.hasOwnProperty(key) and key === "__ko_mapping__" with a &&
• You access source[key] a lot, you could have considered a var value = source[key] and then work with value