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

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.

Last updated

Was this helpful?