Engineering
Angular Observable Inputs
Sometimes using an Observable for an Angular @Input is a good idea as it simplifies handling changes in your components.

Sometimes using an Observable for an Angular @Input is a good idea as it simplifies handling changes in your components. In this post we’ll look at using Observable @Input to do just that.
We’ll use two components AdminComponent (the parent) and EmployeeComponent (the child). The AdminComponent will pass employees to the EmployeeComponent via the EmployeeComponents @Input which will be an Observable of Employees, Observable
@Input as Observable of Employees
Lets start by defining a simple Employee interface so we can properly type our @Input.
// employee.ts
export interface Employee {
name: string;
age: number;
}
Then we need to create our parent component, the AdminComponent.
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { Employee } from './employee';
@Component({
selector: 'app-admin',
template: ``,
styleUrls: ['./admin.component.scss'],
})
export class AdminComponent {
employees = [
{ name: 'bob', age: 45 },
{ name: 'angie', age: 33 },
];
employees$: Observable = of(this.employees);
}
Next we create our child component, the EmployeeComponent.
import { Component, Input } from '@angular/core';
import { Observable } from 'rxjs';
import { Employee } from './employee';
@Component({
selector: 'app-employee',
template: `
name {{ employee.name }}
age {{ employee.age }}
`,
styleUrls: ['./employee.component.scss']
})
export class EmployeeComponent {
@Input('employees') employees$!: Observable;
}
Now we have all we need to display a list of employees, note we don’t need any lifecycle hooks, such as OnInit or OnChanges, making our code slightly less verbose.
We now have a base setup for our Observable Input that we can add additional operators too if we need them. Lets add a map operator that will only return employees over the age of 40. We take the array of employees and filter them as required.
employees$: Observable = of(this.employees).pipe(
map((employees: Employee[]) => employees.filter(employee => employee.age > 40))
);
Two Employee Sources
Sometimes you’ll have multiple sources that need to be combined and used as an input. Below shows two employee sources that are joined and mapped to produce a single array of employees to the EmployeeComponent.
employeesA: Employee[] = [
{ name: 'bob', age: 45 },
{ name: 'angie', age: 33 },
];
employeesB: Employee[] = [
{ name: 'fred', age: 45 },
{ name: 'sue', age: 33 },
];
employeesA$: Observable = of(this.employeesA);
employeesB$: Observable = of(this.employeesB);
employees$ = forkJoin([this.employeesA$, this.employeesB$])
.pipe(
map(([employeesA, employeesB]) => [...employeesA, ...employeesB])
);