# AUR0772

## Error Message

`AUR0772: Invalid @watch decorator config. Expected an expression or a fn but received null/undefined.`

## Description

This error occurs when using the `@watch` decorator, but the required first argument (the expression to watch) is `null` or `undefined`. The `@watch` decorator needs a valid target to observe for changes.

## Cause

The primary cause is providing `null` or `undefined` as the first argument to the `@watch` decorator.

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

export class MyViewModel {
  // Incorrect: Passing null as the expression
  @watch(null)
  nullWatchHandler() { /* ... */ }

  // Incorrect: Passing undefined as the expression
  @watch(undefined)
  undefinedWatchHandler() { /* ... */ }

  // Incorrect: Passing a variable that is null/undefined
  @watch(someVariableThatMightBeNull)
  variableWatchHandler() { /* ... */ }
}
```

## Solution

Ensure that the first argument provided to the `@watch` decorator is always a valid string representing the property path or expression to watch, or a function that selects the value to watch.

1. **Provide a Valid Expression:** Replace `null` or `undefined` with a string expression (e.g., `'myProperty'`, `'user.address.street'`) or a function.
2. **Check Variables:** If using a variable for the expression, ensure it holds a valid string or function before being used in the decorator. Decorator arguments are evaluated at class definition time.

## Example

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

export class MyViewModel {
  private readonly logger = resolve(ILogger);
  firstName: string = 'John';
  lastName: string = 'Doe';
  address: { street: string, city: string } = { street: '123 Main St', city: 'Anytown' };

  // Correct: Watching a simple property using a string
  @watch('firstName')
  firstNameChanged(newValue: string, oldValue: string) {
    this.logger.info(`First name changed from ${oldValue} to ${newValue}`);
  }

  // Correct: Watching a nested property using a string path
  @watch('address.street')
  streetChanged(newValue: string, oldValue: string) {
    this.logger.info(`Street changed from ${oldValue} to ${newValue}`);
  }

  // Correct: Watching an expression using a function
  @watch((vm: MyViewModel) => vm.firstName + ' ' + vm.lastName)
  fullNameChanged(newValue: string, oldValue: string) {
    this.logger.info(`Full name changed from ${oldValue} to ${newValue}`);
  }

  // Correct: Watching multiple properties via a function returning an array
  @watch((vm: MyViewModel) => [vm.address.street, vm.address.city])
  addressChanged(newValues: [string, string], oldValues: [string, string]) {
    this.logger.info(`Address parts changed from ${oldValues?.join(', ')} to ${newValues.join(', ')}`);
  }

  // Incorrect examples that would cause AUR0772:
  // @watch(null)
  // invalidNullHandler() { /* ... */ }

  // @watch(undefined)
  // invalidUndefinedHandler() { /* ... */ }
}

```

## Debugging Tips

* Verify the arguments passed to the `@watch` decorator directly in your component's code.
* Ensure any variables used as arguments to `@watch` are defined and have the correct type (string or function) at the time the class is defined. Remember that decorator code runs early in the class definition process.

```
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.aurelia.io/developer-guides/error-messages/runtime-html/aur0772.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
