# AUR0116

## Error Message

`AUR0116: Ast eval error: cannot assign value to property "<property>" of null/undefined.`

Where `<property>` is the name or key of the property being assigned to.

## Description

This error occurs during the evaluation of a binding expression when an attempt is made to assign a value to a property (using dot notation like `obj.prop = value` or bracket notation like `obj[key] = value`), but the base object (`obj` in the examples) is currently `null` or `undefined`. JavaScript prevents assigning properties to `null` or `undefined`.

## Cause

The most common reasons for this error are:

1. **Object Not Initialized:** The object whose property you are trying to set has not been initialized or has been explicitly set to `null` or `undefined`.
2. **Asynchronous Initialization:** The object is intended to be initialized by an asynchronous operation (e.g., fetching data), but the assignment attempt happens before the operation completes and the object is assigned.
3. **Incorrect Property Access Path:** The expression leading to the object might be incorrect, resulting in `null` or `undefined` being evaluated before the final property assignment (e.g., `data.user.name = 'Test'` when `data.user` is `null`).
4. **Conditional Logic:** The object might exist under certain conditions but be `null` or `undefined` under others, and the assignment occurs when it doesn't exist.

## Solution

1. **Ensure Initialization:** Initialize the object before attempting to assign properties to it. This can be done in the view model's constructor, appropriate lifecycle hooks (`binding`, `bound`, `attaching`), or using default values.
2. **Conditional Assignment:** Use conditional logic (`if.bind` in the template or `if` statements in the view model) to ensure the assignment only happens when the object is not `null` or `undefined`.
3. **Default Values:** Provide default objects in the path if parts might be nullish, for example `data.user = data.user || {}; data.user.name = 'Test';`. Be cautious with this approach as it might hide underlying issues.
4. **Await Asynchronous Operations:** If the object is initialized asynchronously, ensure that any logic attempting property assignments waits for the initialization to complete (e.g., using `async/await` or Promise chaining).

## Example

```html
<!-- Assume 'userProfile' might be null initially -->
<input value.bind="userProfile.email"> <!-- Incorrect: May throw AUR0116 if userProfile is null -->

<!-- Assume 'updateSettings' tries to set 'config.theme' -->
<button click.trigger="updateSettings('dark')">Set Theme</button> <!-- Incorrect: May throw if 'config' is null -->

<!-- Correct: Ensure object exists before binding -->
<template if.bind="userProfile">
  <input value.bind="userProfile.email">
</template>

<!-- Correct: Initialize object in view model before binding -->
```

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

interface UserProfile {
  email: string;
  name: string;
}

interface AppConfig {
  theme: string;
  notifications: boolean;
}

@customElement({ /* ... */ })
export class MyComponent {
  // Initialized to null - assignments will fail until it's an object
  userProfile: UserProfile | null = null;
  config: AppConfig | null = null;

  constructor() {
    // Simulate loading
    setTimeout(() => {
      this.userProfile = { email: 'test@example.com', name: 'Test User' };
      // Forgetting to initialize config would cause errors if updateSettings is called
      // this.config = { theme: 'light', notifications: true };
    }, 1000);
  }

  // Corrected approach: Ensure config exists before assignment
  updateSettings(newTheme: string) {
    if (this.config === null) {
      this.config = { theme: 'light', notifications: true }; // Initialize if null
    }
    this.config.theme = newTheme; // Now safe to assign
  }

  // Alternative: Initialize properties in the constructor or directly
  // userProfile: UserProfile = { email: '', name: '' };
  // config: AppConfig = { theme: 'light', notifications: true };
}
```

## Debugging Tips

* Use `console.log` or breakpoints to inspect the value of the object immediately before the property assignment that causes the error.
* Trace back the code execution to find where the object should have been initialized or why it became `null` or `undefined`.
* Check asynchronous operations (API calls, timeouts) that might be responsible for initializing the object and ensure they complete before assignments occur.
* Verify the full property access path (e.g., `a.b.c`) - ensure that intermediate objects (`a` and `a.b`) are also not `null` or `undefined` if you are assigning to `c`. Consider optional chaining (`a.b?.c = value`) if appropriate, though this prevents the assignment if `a.b` is nullish, which might not be the desired outcome. Direct assignment as in the error requires the path to exist.
