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

<!-- 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>
// 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: '[email protected]' };
    }, 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.

Last updated

Was this helpful?