Carlos Cifuentes
AngularJS → Angular reference

$filter in JavaScript in modern Angular

$filter('name') in controllers and services becomes a direct function call. Angular exports the formatting functions that its pipes use.

Before · AngularJS
app.controller('InvoiceCtrl', function ($filter) {
  var vm = this;
  vm.label = $filter('currency')(vm.total, '$') +
    ' on ' + $filter('date')(vm.createdAt, 'mediumDate');
  vm.active = $filter('filter')(vm.items, { active: true });
  vm.sorted = $filter('orderBy')(vm.active, 'name');
});
After · Angular
import { formatCurrency, formatDate } from '@angular/common';

export class InvoiceComponent {
  private locale = inject(LOCALE_ID);
  items = input.required<Item[]>();
  total = input.required<number>();
  createdAt = input.required<Date>();

  label = computed(() =>
    formatCurrency(this.total(), this.locale, '$', 'USD') +
    ' on ' + formatDate(this.createdAt(), 'mediumDate', this.locale));

  sorted = computed(() => this.items()
    .filter(i => i.active)
    .sort((a, b) => a.name.localeCompare(b.name)));
}

What changes

  • formatDate, formatCurrency, formatNumber and formatPercent from @angular/common replace $filter('date'), $filter('currency') and $filter('number').
  • A pipe class can also be injected and called through transform(), if you add it to providers.
  • $filter('filter') and $filter('orderBy') become Array.filter and Array.sort inside a computed signal.

Migration tip. For custom filters, move the logic to an exported function and make the pipe a thin wrapper around it. Templates and TypeScript code then share one implementation.

Related

Planning a migration or a micro-frontend platform?

In a 20-minute call you describe your situation and I tell you how I'd approach it. If it isn't worth doing yet, I'll say so.

Message me on LinkedIn