# AUR0111

## Error Message

`AUR0111: Ast eval error: expected "<name>" to be a function`

Where `<name>` is the name of the property or variable that was expected to be a function.

## Description

This error occurs during the evaluation of a binding expression when an attempt is made to call something as a function (e.g., `doSomething()`, `item.process()`), but the target of the call is not actually a function type at runtime.

## Cause

The primary cause is that the variable or object property being invoked with `()` does not hold a function. This can happen for several reasons:

1. **Incorrect Type:** The variable/property holds a value of a different type (e.g., string, number, object, null, undefined) instead of a function.
2. **Typo:** The name of the function or the property containing the function is misspelled.
3. **Scope Issue:** The intended function exists but is not accessible from the current binding scope (e.g., it's not a property on the view model or not correctly imported/registered).
4. **Conditional Logic:** The variable might hold a function under some conditions but not others, and the call is attempted when it's not a function.
5. **Lifecycle Issues:** An attempt is made to call a method that is only defined or assigned later in the component lifecycle, or after certain asynchronous operations complete.

## Solution

1. **Verify Type:** Ensure that the variable or property being called is indeed a function at the point of invocation. Use `console.log` or a debugger to inspect its type (`typeof variableName === 'function'`).
2. **Check Spelling:** Double-check the spelling of the function or property name in the binding expression and the view model definition.
3. **Confirm Scope:** Verify that the function is defined on the view model or otherwise accessible within the binding's scope.
4. **Handle Conditional Cases:** If the property might not always be a function, add checks in your template or view model logic before attempting the call (e.g., using `if.bind="typeof myVar === 'function'"` or conditional logic in the view model).
5. **Review Logic/Lifecycle:** Ensure the function is defined and assigned before the binding expression tries to call it.

## Example

```html
<!-- Assume 'calculateValue' should be a function -->

<!-- Incorrect: 'calulateValue' is misspelled -->
<p>Result: ${ calulateValue() }</p>

<!-- Incorrect: 'user.process' is not a function (maybe it's a property) -->
<button click.trigger="user.process()">Process User</button>

<!-- Correct: Calling a function defined on the view model -->
<p>Result: ${ calculateValue() }</p>

<!-- Correct: Calling a method on an object property -->
<button click.trigger="user.activate()">Activate User</button>
```

```typescript
// View Model Example
import { customElement } from 'aurelia';

interface User {
  name: string;
  activate: () => void; // A function property
  status: string; // A non-function property
}

@customElement({ /* ... */ })
export class MyComponent {
  message = 'Hello';
  user: User = {
    name: 'John Doe',
    activate: () => {
      console.log('User activated');
      this.user.status = 'Active';
    },
    status: 'Inactive'
  };

  // Ensure this is actually a function
  calculateValue = () => {
    return 10 * 5;
  };

  // Example of incorrect setup causing the error:
  // calculateValue = 50; // Assigning a number instead of a function

  // Another example: Trying to call 'status' which is a string
  // <button click.trigger="user.status()">Show Status</button> <-- This would cause AUR0111
}

```

## Debugging Tips

* Use browser developer tools to set breakpoints in the relevant view model code or inspect the scope during rendering.
* Log the `typeof` the variable/property right before the call is expected to happen.
* Simplify the binding expression to isolate the function call.
* Check the network tab or component lifecycle methods if the function is expected to be loaded or defined asynchronously.
