ViewModel Observable Management

In many ViewModels, I end up having some observers set up to watch a variable and do something when a change occurs. In these cases, I use Aurelia's ObserverLocator. An important thing with setting up your own observers, however, is that you need to make sure that they are cleaned up by calling the function returned by subscribe.

Since these observers are typically meant to span the life of the view activation, I usually store the unsubscribe functions in an array on the viewmodel and clean them up on deactivate. Building upon what I posted previously with appState, this is what this usually looks like:

import {inject} from 'aurelia-framework';  
import {ObserverLocator} from 'aurelia-framework';  
import {ApplicationState} from '../ApplicationState';

@inject(ApplicationState, ObserverLocator)
export class Home {  
  constructor(appState, observerLocator) {
    this.appState = appState;
    this.observerLocator = observerLocator;
    this.subscriptions = [];

    this.users = [];
    this.sortField = 'username';
    this.sortDesc = false;
  }

  activate (params, queryString, routeConfig) {
    this.loadUsers();

    this.subscriptions.push(
      this.observerLocator.getObserver(this, 'sortField').subscribe(
        (newValue, oldValue) => {
          if (newValue !== oldValue) { this.loadUsers(); }
        })
    );

    this.subscriptions.push(
      this.observerLocator.getObserver(this, 'sortDesc').subscribe(
        (newValue, oldValue) => {
          if (newValue !== oldValue) { this.loadUsers(); }
        })
    );
  }

  deactivate () {
    while (this.subscriptions.length) { this.subscriptions.pop()(); }
  }

  loadUsers () {
    // Get users from server based on sortField/sortDesc, 
    // and put into this.users...
  }
}