LogoLogo
HomeDiscourseBlogDiscord
  • Introduction
  • Introduction
    • Quick start
    • Aurelia for new developers
    • Hello world
      • Creating your first app
      • Your first component - part 1: the view model
      • Your first component - part 2: the view
      • Running our app
      • Next steps
  • Templates
    • Template Syntax
      • Attribute binding
      • Event binding
      • Text interpolation
      • Template promises
      • Template references
      • Template variables
      • Globals
    • Custom attributes
    • Value converters (pipes)
    • Binding behaviors
    • Form Inputs
    • CSS classes and styling
    • Conditional Rendering
    • List Rendering
    • Lambda Expressions
    • Local templates (inline templates)
    • SVG
  • Components
    • Component basics
    • Component lifecycles
    • Bindable properties
    • Styling components
    • Slotted content
    • Scope and context
    • CustomElement API
    • Template compilation
      • processContent
      • Extending templating syntax
      • Modifying template parsing with AttributePattern
      • Extending binding language
      • Using the template compiler
      • Attribute mapping
  • Getting to know Aurelia
    • Routing
      • @aurelia/router
        • Getting Started
        • Creating Routes
        • Routing Lifecycle
        • Viewports
        • Navigating
        • Route hooks
        • Router animation
        • Route Events
        • Router Tutorial
        • Router Recipes
      • @aurelia/router-lite
        • Getting started
        • Router configuration
        • Configuring routes
        • Viewports
        • Navigating
        • Lifecycle hooks
        • Router hooks
        • Router events
        • Navigation model
        • Current route
        • Transition plan
    • App configuration and startup
    • Enhance
    • Template controllers
    • Understanding synchronous binding
    • Dynamic composition
    • Portalling elements
    • Observation
      • Observing property changes with @observable
      • Effect observation
      • HTML observation
      • Using observerLocator
    • Watching data
    • Dependency injection (DI)
    • App Tasks
    • Task Queue
    • Event Aggregator
  • Developer Guides
    • Animation
    • Testing
      • Overview
      • Testing attributes
      • Testing components
      • Testing value converters
      • Working with the fluent API
      • Stubs, mocks & spies
    • Logging
    • Building plugins
    • Web Components
    • UI virtualization
    • Errors
      • Kernel Errors
      • Template Compiler Errors
      • Dialog Errors
      • Runtime HTML Errors
    • Bundlers
    • Recipes
      • Apollo GraphQL integration
      • Auth0 integration
      • Containerizing Aurelia apps with Docker
      • Cordova/Phonegap integration
      • CSS-in-JS with Emotion
      • DOM style injection
      • Firebase integration
      • Markdown integration
      • Multi root
      • Progress Web Apps (PWA's)
      • Securing an app
      • SignalR integration
      • Strongly-typed templates
      • TailwindCSS integration
      • WebSockets Integration
      • Web Workers Integration
    • Playground
      • Binding & Templating
      • Custom Attributes
        • Binding to Element Size
      • Integration
        • Microsoft FAST
        • Ionic
    • Migrating to Aurelia 2
      • For plugin authors
      • Side-by-side comparison
    • Cheat Sheet
  • Aurelia Packages
    • Validation
      • Validation Tutorial
      • Plugin Configuration
      • Defining & Customizing Rules
      • Architecture
      • Tagging Rules
      • Model Based Validation
      • Validation Controller
      • Validate Binding Behavior
      • Displaying Errors
      • I18n Internationalization
      • Migration Guide & Breaking Changes
    • i18n Internationalization
    • Fetch Client
      • Overview
      • Setup and Configuration
      • Response types
      • Working with forms
      • Intercepting responses & requests
      • Advanced
    • Event Aggregator
    • State
    • Store
      • Configuration and Setup
      • Middleware
    • Dialog
  • Tutorials
    • Building a ChatGPT inspired app
    • Building a realtime cryptocurrency price tracker
    • Building a todo application
    • Building a weather application
    • Building a widget-based dashboard
    • React inside Aurelia
    • Svelte inside Aurelia
    • Synthetic view
    • Vue inside Aurelia
  • Community Contribution
    • Joining the community
    • Code of conduct
    • Contributor guide
    • Building and testing aurelia
    • Writing documentation
    • Translating documentation
Powered by GitBook
On this page
  • Table of Contents
  • Benefits of Lambda Expressions
  • Basic Syntax and Valid Usage
  • Inline Expressions in Templates
  • Unsupported Patterns and Restrictions
  • Working with Array Methods
  • Filtering with repeat.for
  • Chaining Operations: Filter, Sort, and Map
  • Event Callbacks Using Lambdas
  • Interpolation Expressions
  • Transforming and Joining Arrays
  • Aggregating with Reduce
  • Advanced Examples
  • Multiple Array Operations Combined
  • Nested Array Transformation
  • Complex Event Handling
  • Real-time Filtering Based on User Input
  • Elaborate Aggregation with Reduce
  • Performance Considerations and Best Practices
  • Common Pitfalls and Debugging Tips

Was this helpful?

Export as PDF
  1. Templates

Lambda Expressions

Enhance your Aurelia applications by reducing boilerplate with powerful lambda expressions. This documentation provides a comprehensive guide to using lambda expressions in Aurelia templates, includin

PreviousList RenderingNextLocal templates (inline templates)

Last updated 3 months ago

Was this helpful?

Lambda expressions in Aurelia templates offer a concise and powerful approach to incorporating JavaScript-like functionality directly within your HTML. By leveraging a subset of JavaScript's arrow function syntax, Aurelia ensures your templates remain expressive, readable, and maintainable.

Table of Contents

Benefits of Lambda Expressions

  • Less Boilerplate: Embed logic inline without extra view-model methods or value converters.

  • Enhanced Readability: Express inline operations in a way that clearly reflects the intended transformation or filtering.

  • Flexibility: Manipulate data on the fly right where it's rendered.

  • Maintainability: Localize small bits of logic with the markup, which in certain scenarios simplifies updates and debugging.

Basic Syntax and Valid Usage

Lambda expressions are defined using JavaScript's arrow function syntax. Supported forms include:

<!-- No parameters -->
() => 42

<!-- Single parameter with parentheses omitted -->
a => a

<!-- Single parameter with explicit parentheses -->
(a) => a

<!-- With rest parameters -->
(...args) => args[0]

<!-- Multiple parameters -->
(a, b) => `${a}${b}`

<!-- Nested lambda -->
a => b => a + b

Inline Expressions in Templates

You can integrate lambda expressions directly in your template expressions for filtering, transforming, or handling events:

<div repeat.for="i of items.filter(item => item.active)">
  ${i.name}
</div>

Unsupported Patterns and Restrictions

Aurelia supports a limited subset of the standard JavaScript arrow function syntax. The following patterns are not supported:

  • Block Bodies: Only expression bodies are permitted.

    // Invalid: Block body is not allowed
    () => { return 42; }
  • Default Parameters: You cannot specify default values.

    // Invalid: Default parameter syntax is not allowed
    (a = 42) => a
  • Destructuring Parameters: Both array and object destructuring are not supported.

    // Invalid: Destructuring parameter
    ([a]) => a
    ({a}) => a

Working with Array Methods

Lambda expressions shine when working with array methods, especially inside repeat.for bindings.

Filtering with repeat.for

Instead of using value converters for filtering, you can directly use lambda expressions:

<div repeat.for="item of items.filter(item => item.isVisible)">
  ${item.name}
</div>

Chaining Operations: Filter, Sort, and Map

You can chain multiple array operations to transform data inline:

<div repeat.for="item of items
  .filter(item => item.selected)
  .sort((a, b) => a.order - b.order)">
  ${item.name}
</div>

Note: Aurelia observes only the properties referenced in the lambda expression. In the above example, changes to selected and order will trigger re-evaluation.

Tip: For sorting that might mutate your original array, use a non-mutating clone:

<div repeat.for="item of items.filter(item => item.active).slice(0).sort((a, b) => a.order - b.order)">
  ${item.name}
</div>

Event Callbacks Using Lambdas

Lambda expressions can simplify event handlers by keeping the logic in the template:

<my-input change.bind="value => updateValue(value)">
<my-button click.trigger="event => handleClick(event)">

This inline style helps clarify what data is being passed to your handler.

Interpolation Expressions

Lambda functions can also be used within interpolation expressions for dynamic data calculations.

Transforming and Joining Arrays

For instance, to render a comma-separated list from an array of keywords:

<p>${keywords.map(x => x.toUpperCase()).join(', ')}</p>

Aggregating with Reduce

Compute aggregate values inline, such as totals or averages:

<p>Total: ${cartItems.reduce((total, item) => total + item.price, 0)}</p>

Advanced Examples

Here are several advanced examples showcasing the versatility of lambda expressions:

Multiple Array Operations Combined

Perform filtering, slicing, sorting, and mapping in one chained expression:

<div repeat.for="user of users.filter(u => u.active)
                              .slice(0, 10)
                              .sort((a, b) => a.name.localeCompare(b.name))">
  ${user.name}
</div>

Nested Array Transformation

Flatten nested structures and dynamically generate lists:

<ul>
  <li repeat.for="category of categories">
    ${category.items.map(item => item.label).join(', ')}
  </li>
</ul>

Complex Event Handling

Pass additional context to event callbacks with inline lambdas:

<button click.trigger="event => deleteItem(event, item.id)">
  Delete
</button>

Real-time Filtering Based on User Input

Implement a dynamic filter that updates as the user types:

<input type="text" value.bind="filterText" placeholder="Filter names..." />
<div repeat.for="person of people.filter(p => p.name.includes(filterText))">
  ${person.name}
</div>

Elaborate Aggregation with Reduce

Calculate averages or other complex aggregates inline:

<p>
  Average Rating: ${products.reduce((sum, product, index, array) =>
                      sum + product.rating / array.length, 0).toFixed(2)}
</p>

Performance Considerations and Best Practices

While lambda expressions keep your templates clean, there are a few points to consider for optimal performance:

  • Observability: Aurelia observes only the properties directly referenced in the lambda. Be sure to include all necessary properties to trigger re-evaluation.

  • Array Mutations: Methods that mutate the array (e.g., sort, splice) won't trigger the binding update. Prefer non-mutating techniques (e.g., using slice before sorting).

  • Complexity: Keep lambda expressions simple where possible. For logic that becomes too complex or involves multiple operations, consider moving it to the view-model.

  • Debugging: Inline expressions can be harder to debug. If you encounter issues, isolating the logic in the view-model might help identify problems.

Common Pitfalls and Debugging Tips

  • Over-Complex Expressions: When lambda logic is too complicated, it might hinder readability and may lead to performance bottlenecks. Refactor complex logic into a dedicated view-model method if necessary.

  • Property Dependencies: If updates to a property do not trigger a re-evaluation, confirm that the property is correctly referenced within the lambda.

  • Mutating Methods: Since some array methods do not automatically trigger binding updates, cloning or using non-mutating methods is recommended.

Introduction
Benefits of Lambda Expressions
Basic Syntax and Valid Usage
Unsupported Patterns and Restrictions
Working with Array Methods
Filtering with repeat.for
Chaining Operations: Filter, Sort, and Map
Event Callbacks Using Lambdas
Interpolation Expressions
Advanced Examples
Performance Considerations and Best Practices
Common Pitfalls and Debugging Tips
Frequently Asked Questions (FAQ)