# 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:

```typescript
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

```typescript
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.
