Jesus is Lord
Jesus is Lord

Reputation: 15399

Why is this knockout observable not being updated?

I am expecting the UI to show "Good-bye". Instead it's showing "How are you?". Why is this happening? In knockout, does disposing of a single subscription stop the observable from working at all?

Here's a plunker: https://plnkr.co/edit/V5g5aQ5wxPGaRL31pUKj

Here's my code:

<!DOCTYPE html>
<html>

  <head>
    <script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
  </head>

  <body>
    <p>
      message: <span data-bind="text: message"></span>
    </p>
    <p>
      messageChanged: <span data-bind="text: messageChanged"></span>
    </p>
  </body>

  <script>
    var viewModel = {
      message: ko.observable('Hello'),
      messageChanged: ko.observable(0)
    };

    var dispose = viewModel.message.subscribe(function _subscribe(newValue) {
      viewModel.messageChanged(viewModel.messageChanged() + 1);
    });

    ko.applyBindings(viewModel);

    viewModel.message('How are you?');

    dispose();

    viewModel.message('Good-bye');

  </script>
</html>

I expect this to be valid code. Here's what the documentation says:

Upvotes: 2

Views: 94

Answers (2)

Priyanka Jain
Priyanka Jain

Reputation: 317

You do not require to call dispose method. In knockout observable automatically update values in UI without calling them explicitly. May be this will resolve your issue. This will also update your message count

<!DOCTYPE html>
<html>
    <head>
        <script src="http://knockoutjs.com/downloads/knockout-3.0.0.debug.js" type="text/javascript"></script>
    </head>
    <body>
        <p>
          message: <span data-bind="text: message"></span>
        </p>
        <p>
          messageChanged: <span data-bind="text: messageChanged"></span>
        </p>
    </body>

    <script>
         var viewModel = {
          message: ko.observable('Hello'),
          messageChanged: ko.observable(0)
        };

        var dispose = viewModel.message.subscribe(function _subscribe(newValue) {
          viewModel.messageChanged(viewModel.messageChanged() + 1);
        });

        ko.applyBindings(viewModel);

        viewModel.message('How are you?');         

        viewModel.message('Good-bye');      
    </script>
</html>

Upvotes: 1

Jesus is Lord
Jesus is Lord

Reputation: 15399

I was disposing incorrectly. Instead of calling the result of subscribe, I should call the dispose property of the result of subscribe.

Here's the documentation:

You can also terminate a subscription if you wish: first capture the return value as a variable, then you can call its dispose function, e.g.:

var subscription = myViewModel.personName.subscribe(function(newValue) { /* do stuff */ });
// ...then later...
subscription.dispose(); // I no longer want notifications

Here's a corrected plunker: https://plnkr.co/edit/hsdESPX1F0k09lH4hThl

Here's the corrected code:

<!DOCTYPE html>
<html>

  <head>
    <script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
  </head>

  <body>
    <p>
      message: <span data-bind="text: message"></span>
    </p>
    <p>
      messageChanged: <span data-bind="text: messageChanged"></span>
    </p>
  </body>

  <script>
    var viewModel = {
      message: ko.observable('Hello'),
      messageChanged: ko.observable(0)
    };

    var subscription = viewModel.message.subscribe(function _subscribe(newValue) {
      viewModel.messageChanged(viewModel.messageChanged() + 1);
    });

    ko.applyBindings(viewModel);

    viewModel.message('How are you?');

    subscription.dispose();

    viewModel.message('Good-bye');

  </script>
</html>

Upvotes: 1

Related Questions