Angular input() / output() Preview

Angular 19 Signals with input() and output()

With Angular 16+, the Composition API offers a modern and reactive way to manage component state using signal(), input(), and output(). In Angular 19, this approach is more powerful than ever, enabling lightweight and reactive component communication.

In this guide, we'll build a Product Dashboard using:

  • input() and output() for reactive component I/O
  • signal() for local state management
  • Standalone components with full signal-based communication

Folder Structure

/components
  ├── product-page/
  │   └── product-page.component.ts
  ├── product-add/
  │   └── product-add.component.ts
  ├── product-list/
  │   └── product-list.component.ts

1. product-add.component.ts – Emits new product using output()

import { Component, output, signal } from '@angular/core';
export interface Product {
  id: number; name: string; price: number;
}
@Component({
  selector: 'product-add',
  standalone: true,
  template: `
    Add Product
    
    
    Add
  `,
})
export class ProductAddComponent {
  name = signal('');
  price = signal(0);
  productAdded = output<Product>();
  addProduct() {
    if (!this.name || this.price() <= 0) {
      return;
    }
    const productAdded: Product = {
      id: Math.floor(Math.random() * 1000),
      name: this.name(),
      price: this.price(),
    }
    this.productAdded.emit(productAdded);
    this.resetFields();
  }
 resetFields() {
   this.name.set('');
   this.price.set(0);
 }
}

2. product-list.component.ts – Consumes products with input()

import { Component, input } from '@angular/core';
import { Product } from '../product-add/product-add.component';

@Component({
  selector: 'product-list',
  standalone: true,
  template: `

  Product List
  Si cargo 
  
    @for (product of products(); track product.id; let idx = $index) {
      
        {{ product.name }} - ${{ product.price }}
      
    }
  


  `
})
export class ProductListComponent {
  products = input.required<Product[]>();
}

3. product-page.component.ts – Orchestrates everything with signal()

import { Component, signal } from '@angular/core';
import { ProductAddComponent, Product } from '../product-add/product-add.component';
import { ProductListComponent } from '../product-list/product-list.component';

@Component({
  selector: 'product-page',
  standalone: true,
  imports: [ProductAddComponent, ProductListComponent],
  template: `
    Product Dashboard
    
    
  `
})
export class ProductPageComponent {
  products = signal<Product[]>([]);

  addProduct(newProduct: Product) {
    this.products.update(p => [...p, newProduct]);
  }
}

What This Shows

Feature Demonstrated
input.required() In ProductListComponent
output() In ProductAddComponent
signal() In ProductPageComponent
Reactive flow Between child and parent
Standalone components