Search code examples
knockout.jsknockout-binding-handlers

Knockout JS: Computed observable failing to update


I am having trouble getting my knockout text observable to update with a computed or pureComputed ko function.

<li data-bind="css: { active: route().page === 'login'}">
    <a href="#"><label data-bind="text: logOption"></label></a>
</li>

var vm = {
    route: params.route,
    logOption: ko.pureComputed(function() {
       return userFunctions.isLoggedIn(session.user) ? "Log-out" : "Log-in";
      })
   }
  return vm;

The binding is working, however it doesn't update when I log in or log out.

A previous knockout click binding would update whenever I clicked on the element, so I know that the userFunctions.isLoggedIn(sessions.user) does itself update properly depending on the log in / log out status.

I would like the text:logOption to update with "log in" or "log out" depending on the status, but it seems as if knockout is not observing the change in status of the userFunctions.isLoggedIn(sessions.user) within the computed variable?


Solution

  • Well, there are a lot of things wrong with your approach.

    First off, it is not a client-side responsibility to handle login/logout. For this reason, it should not be a link, but a POSTed form from where you initiate the process.

    About your particular question, it does not work because the value you make the logOption to rely on is not an observable. Knockout has no way of knowing that the value of something has changed unless it is an observable - in other words, computed observables don't not work like they poll the value every 0.x seconds or so to see if there was a change. How do you, then, expect it to realize there was a change in the value?

    The solution therefore is that you must implement the logOption value so that it depends on an observable and change the value of it. This should be the solution in other, similar circumstances, but as far as login management is concerned, you should simply opt for a server-side solution.