# AUR0773

## Error Message

`AUR0773: Invalid @watch decorator change handler config. Method "<methodName>" not found in class <ClassName>`

Where `<methodName>` is the name provided as the change handler, and `<ClassName>` is the name of the class where `@watch` was used.

## Description

This error occurs when using the `@watch` decorator **as a class decorator** with a configuration object, and the `changeHandler` property in that configuration is a string, but there is no method with that specified name on the decorated class.

The `@watch` decorator needs a valid function (either provided directly or found by name on the class) to call when the watched expression changes.

## Cause

This error specifically happens under these conditions:

1. `@watch` is used as a class decorator: `@watch({...})(MyClass)` or `@watch({...}) class MyClass { ... }`
2. A configuration object is passed to `@watch`.
3. The configuration object has a `changeHandler` property that is a string (e.g., `{ changeHandler: 'myMethodName' }`).
4. The class (`MyClass` in the example) does **not** have a method named `myMethodName`.

```typescript
import { watch } from '@aurelia/runtime-html';

// Incorrect: 'valueChangedHandler' method does not exist on the class
@watch({
  expression: 'value',
  changeHandler: 'valueChangedHandler' // Typo or missing method
})
export class MyViewModel {
  value: string = 'test';

  // Missing the required 'valueChangedHandler' method
  // valueChangedHandler(newValue, oldValue) { /* ... */ }
}

// Incorrect: changeHandler name mismatch
@watch({
  expression: 'count',
  changeHandler: 'handleCountChange'
})
export class Counter {
  count: number = 0;

  // Method exists, but name doesn't match the changeHandler string
  countChanged(newValue, oldValue) {
    console.log(newValue, oldValue);
  }
}
```

## Solution

1. **Verify Method Name:** Ensure the string provided in the `changeHandler` property exactly matches the name of an existing method on the decorated class. Check for typos.
2. **Implement the Method:** If the method is missing, implement it on the class with the correct name.
3. **Use Method Decorator:** Alternatively, apply `@watch` directly to the handler method itself instead of using it as a class decorator with a string `changeHandler`. This is often simpler and less prone to typos.

## Example

```typescript
import { watch, resolve } from '@aurelia/runtime-html';
import { ILogger } from '@aurelia/kernel';

// Correct: Using @watch as a class decorator with a valid string changeHandler
@watch({
  expression: 'value',
  changeHandler: 'valueChangedHandler' // Matches the method name below
})
export class MyViewModel {
  private readonly logger = resolve(ILogger);
  value: string = 'test';

  // The method exists with the correct name
  valueChangedHandler(newValue: string, oldValue: string) {
    this.logger.info(`Value changed via class decorator: ${oldValue} -> ${newValue}`);
  }
}

// Correct: Using @watch as a method decorator (often preferred)
export class AnotherViewModel {
  private readonly logger = resolve(ILogger);
  count: number = 0;

  // Apply @watch directly to the handler method
  @watch('count')
  handleCountChange(newValue: number, oldValue: number) {
    this.logger.info(`Count changed via method decorator: ${oldValue} -> ${newValue}`);
  }
}


// Incorrect setup causing AUR0773:
// @watch({
//   expression: 'data',
//   changeHandler: 'dataHandler' // No method named 'dataHandler' exists
// })
// export class BrokenViewModel {
//   data: any = null;
//   dataChanged(newValue, oldValue) { /* Handler exists, but wrong name */ }
// }
```

## Debugging Tips

* Carefully compare the string value of the `changeHandler` property in the `@watch` configuration object with the method names defined in your class.
* Check for subtle differences like capitalization or spelling errors.
* Consider refactoring to use `@watch` as a method decorator on the handler function, which eliminates the need for the string name lookup.
