# AUR0506

## Error Message

`AUR0506: Invalid callback for @watch decorator: <callback>`

Where `<callback>` represents the value that was provided as the callback but is not a function.

## Description

This error occurs when using the `@watch` decorator in a view model, but the provided callback (the function that should execute when the watched property changes) is not actually a function type at runtime. The `@watch` decorator requires a valid function to call when changes are detected.

## Cause

1. **Incorrect Callback Type:** The most common cause is providing a value that is not a function as the callback argument to `@watch`. This could be a typo in a function name (string), a property that isn't a function, `null`, `undefined`, etc.
2. **Callback Not Defined:** The function specified as the callback might not be defined on the view model class, or it might be misspelled.
3. **Conditional Assignment:** The property intended to hold the callback function might be conditionally assigned, and `@watch` is evaluated when the property holds a non-function value.

The `@watch` decorator can be used in several ways:

* `@watch(expression)`: Decorating a method directly. The method itself is the callback.
* `@watch(expression, callbackFn)`: Decorating the class. `callbackFn` must be a function.
* `@watch(callbackFn)`: Decorating the class. Watches the class instance, `callbackFn` must be a function.
* `@watch(objectProperty)`: Decorating a callback method. `objectProperty` expression is watched.

This error typically relates to the forms where an explicit callback function is provided or expected.

## Solution

1. **Verify Callback is a Function:** Ensure that the value passed as the callback to `@watch` is indeed a function defined on your view model class or a valid imported function.
2. **Check Spelling:** Double-check the spelling of the callback function name provided to `@watch` or the name of the decorated method.
3. **Ensure Definition:** Confirm that the callback function is correctly defined within the view model class.
4. **Use Correct Decorator Syntax:** Ensure you are using the `@watch` decorator syntax correctly for your intended use case (decorating a method vs. decorating a class).

## Example

```typescript
import { watch, customElement } from 'aurelia';

@customElement({ name: 'watch-example', template: '<input value.bind="firstName"> ${fullName}' })
// Example 1: Watching an expression, calling a class method (must exist)
@watch(c => c.firstName, 'handleNameChange')
// Example 2: Watching the whole view model instance (callback must be a function)
// @watch(viewModelChangedCallback) // Assuming viewModelChangedCallback is defined
export class WatchExample {
  public firstName: string = 'John';
  public lastName: string = 'Doe';
  public fullName: string = 'John Doe';

  // Correct callback method for Example 1
  handleNameChange(newValue: string, oldValue: string) {
    console.log(`First name changed from ${oldValue} to ${newValue}`);
    this.updateFullName();
  }

  // Example 3: Decorating a method directly (method is the callback)
  @watch(c => c.lastName)
  lastNameChanged(newValue: string, oldValue: string) {
    console.log(`Last name changed from ${oldValue} to ${newValue}`);
    this.updateFullName();
  }

  updateFullName() {
    this.fullName = `${this.firstName} ${this.lastName}`;
  }

  // --- Incorrect Usage Leading to AUR0506 ---

  // Incorrect: Providing a string that isn't a valid method name
  // @watch(c => c.firstName, 'handleNameChangeTypo')

  // Incorrect: Providing a property that isn't a function
  // notAFunction = 'hello';
  // @watch(c => c.firstName, 'notAFunction')

  // Incorrect: Providing undefined/null callback (if syntax allowed it)
  // @watch(c => c.firstName, undefined)

}

// Correct callback function for Example 2 (if used)
function viewModelChangedCallback(viewModel: WatchExample, changes: unknown) {
  console.log('ViewModel instance changed:', viewModel, changes);
}
```

## Debugging Tips

* Identify the component (`<ControllerName>`) and the specific `@watch` decorator causing the issue.
* Examine the arguments passed to the `@watch` decorator.
* If a callback name (string) is provided, verify that a method with that exact name exists on the class.
* If a function reference is provided directly, ensure it's correctly defined and imported if necessary.
* Use `console.log(typeof this.callbackMethodName)` in the constructor or `binding` lifecycle hook to check the type of the intended callback just before `@watch` is likely processed.
* Temporarily remove the problematic `@watch` decorator to confirm it's the source of the error.
