# AUR0114

## Error Message

`AUR0114: Ast eval error: cannot access property "<property>" of <value>.`

Where `<property>` is the name of the property being accessed, and `<value>` is typically `null` or `undefined`.

## Description

This error occurs during the evaluation of a binding expression when an attempt is made to access a property via dot notation (e.g., `user.name`) on an object that is currently `null` or `undefined`.

## Cause

The root cause is trying to read a property from a value that doesn't have properties. This usually happens because:

1. **Uninitialized Object:** The object variable (`user` in the example) has not yet been assigned a value, or has been explicitly set to `null` or `undefined`.
2. **Asynchronous Data:** Data is being loaded asynchronously, and the binding expression evaluates before the data (and thus the object) is available.
3. **Function/API Call Result:** A function or method called returns `null` or `undefined` instead of the expected object.
4. **Conditional Logic:** The variable might hold an object under some conditions but `null` or `undefined` under others.

## Solution

1. **Use Optional Chaining (`?.`):** The safest and most common solution is to use the optional chaining operator (`?.`). This will stop the evaluation and return `undefined` if the object on the left is `null` or `undefined`, preventing the error. Example: `user?.name`.
2. **Provide Default Values:** Ensure the object is initialized with a default value (e.g., an empty object `{}`) in the view model.
3. **Conditional Rendering/Binding:** Use `if.bind` to render the part of the template that accesses the property only when the object is not `null` or `undefined`.
4. **Nullish Coalescing (`??`):** For displaying a default value when the property access results in `undefined` (due to optional chaining or otherwise), use the nullish coalescing operator. Example: `${user?.name ?? 'N/A'}`.

## Example

```html
<!-- Assume 'currentUser' might be null initially -->

<!-- Incorrect: Throws AUR0114 if 'currentUser' is null -->
<p>Welcome, ${ currentUser.firstName }</p>
<input type="text" value.bind="currentUser.email">

<!-- Correct: Using Optional Chaining (?.) -->
<p>Welcome, ${ currentUser?.firstName }</p>
<input type="text" value.bind="currentUser?.email">

<!-- Correct: Optional Chaining with Nullish Coalescing (??) for default -->
<p>Welcome, ${ currentUser?.firstName ?? 'Guest' }</p>
<input type="text" value.bind="currentUser?.email ?? ''">

<!-- Correct: Using if.bind to conditionally render -->
<template if.bind="currentUser">
  <p>Welcome, ${ currentUser.firstName }</p>
  <input type="text" value.bind="currentUser.email">
</template>
<template else>
  <p>Loading user...</p>
</template>
```

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

interface User {
  id: number;
  firstName: string;
  email: string;
}

@customElement({ /* ... */ })
export class UserProfile {
  // currentUser might be null until loaded
  currentUser: User | null = null;

  constructor() {
    // Simulate async loading
    setTimeout(() => {
      this.currentUser = { id: 1, firstName: 'Jane', email: 'jane@example.com' };
    }, 1500);
  }

  // Alternative: Initialize with a default object (if appropriate)
  // currentUser: User | null = { id: 0, firstName: '', email: '' };
}
```

## Debugging Tips

* Identify the exact expression causing the error (e.g., `currentUser.firstName`).
* Inspect the value of the object part (`currentUser`) just before the property access using `console.log` or debugger tools. Check if it's `null` or `undefined`.
* Trace back where `currentUser` is assigned its value. Pay attention to asynchronous operations (like `fetch`, `setTimeout`) or conditional logic that might result in a null/undefined state.
* Implement optional chaining (`?.`) as the primary fix.
