self.MyObservableProperty.subscribe() cancel event

1,038 views
Skip to first unread message

cwood...@gmail.com

unread,
Feb 7, 2013, 1:55:56 PM2/7/13
to knock...@googlegroups.com
Hello all,

Let's say I have an observable property like: self.MyObservableProperty. I also have also used the subscribed function ( self.MyObservableProperty.subscribe() ), so I know when my property changes. 

My question is, how do I cancel or stop propagation?

In my scenario, when the user changes a value, I need to be able to query the database to see if the value can be updated. If the update fails, I need to be able to revert back to the original value.

Is this possible?

Thanks!

Matteo Pagliazzi

unread,
Feb 8, 2013, 12:29:46 PM2/8/13
to knock...@googlegroups.com, cwood...@gmail.com
Actually it isn't part of Knockout but it's very easy to write a function that return both the old and the new value. Here you can find various examples https://github.com/SteveSanderson/knockout/pull/520, if you need some more help, or don't understand the code in the link, just ask

cwood...@gmail.com

unread,
Feb 8, 2013, 1:51:18 PM2/8/13
to knock...@googlegroups.com, cwood...@gmail.com
Thank you for your response. After looking at the suggested post, it doesn't look like this is the answer to my situation. If it is, I guess I'm not able to follow the logic in the code snippets. Would you mind clarifying it for me?

Thanks!

Matteo Pagliazzi

unread,
Feb 8, 2013, 2:59:37 PM2/8/13
to knock...@googlegroups.com, cwood...@gmail.com
If I understood what you are trying to do:

You have an observable:

var myObservable = ko.observable();

You subscribe to the observable and use a function to query the database:

myObservable.subscribe(function(){
   
if(!save()){
     
//Here you want to handle the case when the save fails...
   
}
}


And if querying to the database fails you want to use the old value in the observable, right?

cwood...@gmail.com

unread,
Feb 8, 2013, 3:18:09 PM2/8/13
to knock...@googlegroups.com, cwood...@gmail.com
Yes, that sounds exactly like what I'm trying to do. Here's my pseudo code:

 self.myObservable.subscribe(function (newValue) {
       
//Attempt to update the record with the newValue
        queryDatabase
(newValue);

       
//If the update fails, use the old value
       
if (failed) {          
           
return oldValue;
       
}
       
//If the update succeeds, use the new value in the observable
        commit
(newValue);
   
});

Thank you so much for your help!!

Matteo Pagliazzi

unread,
Feb 9, 2013, 11:17:54 AM2/9/13
to knock...@googlegroups.com, cwood...@gmail.com
Ok, to achieve the code you posted you can't use the normal subscribe function because the oldValue isn't exposed but only the new one so you should use one of the snippets in the page I linked like this:

ko.subscribable.fn.subscribeChanged = function(callback) {
   
if (!this.previousValueSubscription) {
       
this.previousValueSubscription = this.subscribe(function(_previousValue) {
           
this.previousValue = _previousValue;
       
}, this, 'beforeChange');
   
}
   
return this.subscribe(function(latestValue) {
       
callback(latestValue, this.previousValue);
   
}, this);
};

And then use it:

self.myObservable.subscribeChanged(function (newValue, oldValue) {

       
//Attempt to update the record with the newValue
        queryDatabase
(newValue);

       
//If the update fails, use the old value
       
if (failed) {
         
           
myObservable(oldValue);
       
}
   
});

But that won't work since newValue is already set when the subscription callback is called so setting the value to oldValue will cause the subscription to reevaluate.

What you need is the possibility to commit and rollback to the previous value if the query to the database fails. If you search google for "knockout commit" you'll find tons of examples, try to see if you find one that works as you need. I f yo don't find anything, I'll try to create something

cwood...@gmail.com

unread,
Feb 11, 2013, 9:18:25 AM2/11/13
to knock...@googlegroups.com, cwood...@gmail.com
Thank again for your help. However, I haven't found an example that will fit my needs. All of the commit/rollback examples I have found are tied into a button click event. Unfortunately, I need something that happens using the observable's subscription. 

I'm using the grid from jqwidgets to display and edit records. I have a column that holds a value of true/false that is represented by a checkbox. When the user clicks the check box, I need to be able to query the database to make sure that value can change from true to false (or false to true). Because I'm using the jqwidgets grid, I'm unable to commit/rollback via a button click event.

If you can help, I'd greatly appreciate it.

Again, thanks for your help.
Reply all
Reply to author
Forward
0 new messages