# AUR0774

## Error Message

`AUR0774: Invalid @watch decorator usage: decorated target <targetName> is not a class method.`

Where `<targetName>` is the name of the property or field that was incorrectly decorated.

## Description

This error occurs when the `@watch` decorator is applied to something other than its intended targets: a class method (when used as a method decorator) or a class definition (when used as a class decorator with a configuration object).

## Cause

The `@watch` decorator is designed for specific use cases:

1. **Method Decorator:** To automatically call the decorated method when a specified expression changes.

   ```typescript
   class MyClass {
     @watch('expression')
     myHandlerMethod() { /* ... */ }
   }
   ```
2. **Class Decorator:** To specify watchers via a configuration object.

   ```typescript
   @watch({ expression: 'expr', changeHandler: 'handlerMethodName' })
   class MyClass {
     handlerMethodName() { /* ... */ }
   }
   ```

This error (AUR0774) occurs if you try to apply `@watch` to other kinds of class members, such as:

* **Class Fields/Properties:**

  ```typescript
  class MyClass {
    @watch('someExpression') // Incorrect: Applied to a property
    myProperty: string = 'value';
  }
  ```
* **Getters/Setters:**

  ```typescript
   class MyClass {
     _value: string;
     @watch('someExpression') // Incorrect: Applied to a getter
     get myValue() { return this._value; }
   }
  ```

The decorator logic specifically checks if `context.kind` (from decorator metadata) is `'method'` or `'class'` depending on how it's invoked. If it's anything else (like `'field'`, `'getter'`, `'setter'`, etc.), this error is thrown.

## Solution

Ensure that the `@watch` decorator is only applied to:

1. **A standard class method:** when you want that method to be the change handler.
2. **The class definition itself:** when you are providing a configuration object with `expression` and `changeHandler` properties.

Do not apply `@watch` to class fields (properties), getters, or setters. If you need to react to changes related to these, watch the underlying properties or use other appropriate patterns.

## Example

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

export class MyViewModel {
  private readonly logger = resolve(ILogger);
  firstName: string = 'John';
  lastName: string = 'Doe';
  userId: number = 1;

  // Correct: @watch applied to a method
  @watch('firstName')
  firstNameChanged(newValue: string, oldValue: string) {
    this.logger.info(`First name changed: ${oldValue} -> ${newValue}`);
  }

  // Correct: @watch applied to the class
  @watch({ expression: 'lastName', changeHandler: 'lastNameChangedHandler' })
  static { /* Class decorator usage */ }

  lastNameChangedHandler(newValue: string, oldValue: string) {
     this.logger.info(`Last name changed: ${oldValue} -> ${newValue}`);
  }


  // Incorrect: @watch applied to a property/field - Causes AUR0774
  // @watch('userId')
  // watchedUserId: number = this.userId;


  private _internalValue: string = 'initial';
  // Incorrect: @watch applied to a getter - Causes AUR0774
  // @watch('somethingElse')
  // get computedValue(): string {
  //   return this._internalValue.toUpperCase();
  // }

  // Incorrect: @watch applied to a setter - Causes AUR0774
  // @watch('yetAnotherThing')
  // set computedValue(value: string) {
  //   this._internalValue = value;
  // }
}

// Correct class decorator usage syntax
@watch({ expression: 'userId', changeHandler: 'userIdChangedHandler' })
export class UserComponent {
   private readonly logger = resolve(ILogger);
   userId: number = 10;

   userIdChangedHandler(newValue: number, oldValue: number){
      this.logger.info(`User ID changed: ${oldValue} -> ${newValue}`);
   }
}
```

## Debugging Tips

* Locate the `@watch` decorator mentioned in the stack trace.
* Verify what kind of class member it is attached to (method, field, getter, setter, class).
* Move the `@watch` decorator to the appropriate handler method or use it as a class decorator with the correct configuration object if necessary.
