# AUR0115

## Error Message

`AUR0115: Ast eval error: cannot access key "<key>" of <value>.`

Where `<key>` is the key (property name or index) 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 or element via keyed access (square bracket notation, e.g., `array[index]`, `object[propertyName]`) on a value that is currently `null` or `undefined`.

## Cause

The fundamental cause is attempting to read a keyed property from a value that cannot have properties (like `null` or `undefined`). Common scenarios include:

1. **Uninitialized Object/Array:** The object or array variable (`array`, `object` in the examples) has not been assigned a value yet, or is explicitly `null` or `undefined`.
2. **Asynchronous Data Loading:** The binding expression evaluates before the array or object containing the desired key is loaded or populated.
3. **Function/API Call Result:** A function returns `null` or `undefined` instead of the expected object or array.
4. **Invalid Key/Index:** While not the direct cause of *this* specific error (that would usually result in `undefined`), an invalid key or index might be used on an object/array that *subsequently* becomes `null` or `undefined`.

## Solution

1. **Use Optional Chaining (`?.`):** Apply optional chaining before the keyed access. This safely stops the evaluation and returns `undefined` if the object/array is `null` or `undefined`. Example: `object?.[key]`, `array?.[index]`.
2. **Provide Default Values:** Initialize the variable with a default value (e.g., an empty array `[]` or object `{}`) in the view model.
3. **Conditional Rendering/Binding:** Use `if.bind` to only render or evaluate the binding when the object/array is not `null` or `undefined`.
4. **Nullish Coalescing (`??`):** Combine with optional chaining to provide a default value if the access results in `undefined`. Example: `${array?.[index] ?? 'Default Value'}`.

## Example

```html
<!-- Assume 'settings' object or 'items' array might be null/undefined -->
<!-- Assume 'currentKey' and 'currentIndex' hold the desired key/index -->

<!-- Incorrect: Throws AUR0115 if 'settings' or 'items' is null/undefined -->
<p>Setting: ${ settings[currentKey] }</p>
<p>Item: ${ items[currentIndex] }</p>

<!-- Correct: Using Optional Chaining (?.) -->
<p>Setting: ${ settings?.[currentKey] }</p>
<p>Item: ${ items?.[currentIndex] }</p>

<!-- Correct: Optional Chaining with Nullish Coalescing (??) -->
<p>Setting: ${ settings?.[currentKey] ?? 'Default Setting' }</p>
<p>Item: ${ items?.[currentIndex] ?? 'No Item' }</p>

<!-- Correct: Using if.bind -->
<template if.bind="settings">
  <p>Setting: ${ settings[currentKey] }</p>
</template>
<template if.bind="items">
  <p>Item: ${ items[currentIndex] }</p>
</template>
```

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

@customElement({ /* ... */ })
export class ConfigDisplay {
  // These might be null until loaded
  settings: Record<string, string> | null = null;
  items: string[] | undefined = undefined;

  currentKey = 'theme';
  currentIndex = 0;

  constructor() {
    // Simulate async loading
    setTimeout(() => {
      this.settings = { theme: 'dark', fontSize: '14px' };
      this.items = ['Apple', 'Banana', 'Cherry'];
    }, 1500);
  }

  // Alternative: Initialize with defaults
  // settings: Record<string, string> | null = {};
  // items: string[] | undefined = [];
}
```

## Debugging Tips

* Pinpoint the expression using square bracket access (`[...]`).
* Use browser developer tools or `console.log` to check the value of the variable *before* the square brackets (`settings`, `items` in the example) at the time of evaluation. Verify if it's `null` or `undefined`.
* Examine how and when this variable gets its value, looking for async operations or conditions that could leave it nullish.
* Apply optional chaining (`?.`) before the square brackets as the most direct fix.
