AUR0107

Error Message

AUR0107: Ast eval error: expression is not a function.

Description

This error occurs during the evaluation of a binding expression when an attempt is made to invoke an expression using call syntax (()), but the expression itself evaluates to a value that is not a function type (e.g., it evaluates to a string, number, object, null, or undefined).

This is similar to AUR0111 (ast_name_is_not_a_function), but typically occurs when the part being called is itself a computed expression rather than a direct variable or property name.

Cause

The fundamental cause is trying to execute something that isn't executable. This often happens when:

  1. Incorrect Return Type: An inner expression (e.g., a function call, a property access) returns a non-function value, which is then immediately invoked. Example: getHandler()() where getHandler() returns a string instead of a function.

  2. Array/Object Access: Attempting to call an element retrieved from an array or object that isn't a function. Example: actions[type]() where actions[type] resolves to null or a non-function value.

  3. Typo/Logic Error: A simple mistake in the expression logic leads to a non-function value being in the position where a function is expected for invocation.

Solution

  1. Verify Expression Result: Ensure that the expression preceding the () evaluates to a function at runtime. Use console.log or debugging tools to inspect the value and its type just before the call attempt.

  2. Check Function Returns: If the expression involves a function call (like getHandler()()), verify that the inner function (getHandler) correctly returns another function under all conditions.

  3. Check Array/Object Contents: If accessing an array element or object property before calling (like actions[type]()), ensure the value stored at that index/key is indeed a function. Provide defaults or add checks if necessary.

  4. Correct Logic: Review the binding expression for any logical errors or typos.

Example

<!-- Assume 'getAction' is supposed to return a function based on 'status' -->
<!-- Assume 'callbacks' is an object where values should be functions -->

<!-- Incorrect: 'getAction(status)' might return null or a string -->
<button click.trigger="getAction(status)()">Perform Action</button>

<!-- Incorrect: 'callbacks[key]' might not exist or not be a function -->
<div mousemove.trigger="callbacks[key]()">Handle Callback</div>

<!-- Correct: Ensure the expression results in a function before calling -->
<!-- (Correction often needs to happen in the view model logic) -->
<button click.trigger="performAction()">Perform Action</button> <!-- VM handles lookup -->
// View Model Example
import { customElement } from 'aurelia';

@customElement({ /* ... */ })
export class MyComponent {
  status = 'pending';
  key = 'onMove';

  callbacks: Record<string, (() => void) | null> = {
    onMove: () => console.log('Moved!'),
    onEnter: null // Example non-function
  };

  getAction(currentStatus: string): (() => void) | null {
    if (currentStatus === 'pending') {
      return () => console.log('Processing pending action...');
    } else if (currentStatus === 'complete') {
      // Incorrectly returning a string instead of a function could cause AUR0107
      // return 'Action Complete';
      return () => console.log('Action Complete');
    }
    return null; // Returning null would also cause AUR0107 if called
  }

  // Safer approach for the template
  performAction() {
    const action = this.getAction(this.status);
    if (typeof action === 'function') {
      action();
    } else {
      console.warn('No action available for status:', this.status);
    }
  }

  // Safer approach for callbacks
  handleCallback(callbackKey: string) {
     const callback = this.callbacks[callbackKey];
     if(typeof callback === 'function') {
       callback();
     }
  }
  // In template: <div mousemove.trigger="handleCallback(key)">Handle Callback</div>
}

Debugging Tips

  • Isolate the complex expression being called in the template.

  • Use console.log or breakpoints in the view model to evaluate the parts of the expression and determine what the non-function value is and why it's occurring.

  • Refactor complex call logic into view model methods for better clarity and easier debugging, performing necessary type checks within the method before invocation.

Last updated

Was this helpful?