AUR0508

Error Message

AUR0508: Observer for property <property> does not support change handler.

Where <property> is the name of the bindable property defined with a changeHandler.

Description

This error occurs when a custom element defines a bindable property using @bindable (or bindables) and specifies a changeHandler method name, but the observation mechanism Aurelia selects for that property does not have the capability to invoke the specified change handler method when the property's value changes.

Cause

Similar to AUR0507 (coercion support), this usually relates to the observation strategy used for the property:

  1. Custom Observation Strategy: A custom observer might be in use for the property, and that observer lacks the necessary implementation to detect and call the method specified by the changeHandler option in the bindable definition. Standard Aurelia observers for view model properties generally support change handlers.

  2. Non-Standard Property Definition: The property might be defined in a way that hinders standard observation supporting change handlers (though this is less likely than with coercion).

  3. Internal Framework Issue (Unlikely): A potential mismatch or bug in how Aurelia links the bindable definition's changeHandler to the selected property observer.

Standard usage should work:

import { bindable } from 'aurelia';

export class MyComponent {
  @bindable({ changeHandler: 'countChanged' })
  public count: number = 0; // Standard usage, typically works

  countChanged(newValue: number, oldValue: number) {
    console.log(`Count changed from ${oldValue} to ${newValue}`);
  }
}

The error implies that the observer assigned to count (or a similar property) cannot fulfill the request to call countChanged when the value is updated via a binding.

Solution

  1. Verify Change Handler Name: Double-check that the method name specified in changeHandler: 'methodName' exactly matches a method defined on the view model class.

  2. Review Property Definition: Ensure the bindable property is a standard class property.

  3. Check for Custom Observers: Investigate if custom observation logic is affecting the property. If so, the custom observer must be enhanced to look for and invoke the changeHandler method from the bindable definition when its setValue (or equivalent) method is called. The observer needs access to both the view model instance (to call the handler method) and the bindable definition.

  4. Use Alternative Notification: If the observer cannot be fixed, consider alternative ways to react to changes, such as using the @watch decorator instead of a changeHandler, or performing checks in lifecycle hooks like propertyChanged (if applicable to the component type).

Example

import { bindable, IObserverLocator, IBindingContext, LifecycleFlags } from 'aurelia';

// --- Standard working example ---
export class StandardHandlerComponent {
  @bindable({ changeHandler: 'valueChanged' })
  public value: string = '';

  valueChanged(newValue: string, oldValue: string) {
    console.log(`Value changed from ${oldValue} to ${newValue}`);
  }
}

// --- Scenario potentially causing the error ---

// Imagine a custom observer that doesn't support invoking change handlers
class NonHandlingObserver {
  constructor(private obj: any, private key: string) {}
  getValue() { return this.obj[this.key]; }
  setValue(newValue: any) {
    // This observer sets the value but does NOT check for or call
    // any 'changeHandler' defined on the bindable.
    this.obj[this.key] = newValue;
  }
  // ... other observer methods ...
  subscribe() {}
  unsubscribe() {}
}

// A custom element potentially using this observer
export class CustomObservedHandlerComponent {
  // Assume Aurelia uses NonHandlingObserver for 'config'
  @bindable({ changeHandler: 'configUpdated' }) // Change handler defined
  public config: object | null = null;

  configUpdated(newValue: object | null, oldValue: object | null) {
    // This method will NOT be called if NonHandlingObserver is used,
    // and AUR0508 will be thrown during binding setup.
    console.log('Config updated');
  }

  // When <custom-observed-handler-component config.bind="..."></custom-observed-handler-component>
  // is processed, Controller#addBinding sees the 'changeHandler' but finds
  // the NonHandlingObserver doesn't support it, throwing AUR0508.
}

// --- Alternative using @watch (if changeHandler is problematic) ---
import { watch } from 'aurelia';

export class WatchAlternativeComponent {
  @bindable() // No changeHandler here
  public config: object | null = null;

  // Use @watch to react to changes instead
  @watch((c: WatchAlternativeComponent) => c.config)
  configChanged(newValue: object | null, oldValue: object | null) {
    console.log('Config changed (via @watch):', newValue);
    // Perform actions previously in the change handler
  }
}

Debugging Tips

  • Identify the <property> from the error message.

  • Verify the @bindable definition for this property and ensure the changeHandler name is spelled correctly and matches a method on the view model.

  • Check for custom observation configurations affecting this property.

  • Set breakpoints in Controller#addBinding (around line 1280 in templating/controller.ts). Inspect the bindable definition and the targetObserver. Does the observer have properties or methods suggesting change handler support (e.g., a hasChangeHandler flag or specific methods)? This might involve inspecting Aurelia's internal observer types.

  • Try removing the changeHandler from the @bindable definition. If the error goes away, it confirms the issue is with the observer's lack of support. Consider using @watch as an alternative if fixing the observer isn't feasible.

Last updated

Was this helpful?