Carlos Cifuentes
AngularJS → Angular reference

$scope.$emit in modern Angular

$emit sent an event up through every ancestor scope. An output() reaches only the direct parent, with a typed payload.

Before · AngularJS
// child controller
$scope.$emit('item:selected', item);

// some ancestor controller
$scope.$on('item:selected', function (event, item) {
  event.stopPropagation();
  vm.selected = item;
});
After · Angular
// item-row.component.ts
export class ItemRowComponent {
  item = input.required<Item>();
  selected = output<Item>();
}
// its template
<button (click)="selected.emit(item())">Select</button>

// parent template
@for (item of items(); track item.id) {
  <app-item-row [item]="item" (selected)="current.set($event)" />
}

What changes

  • Outputs do not bubble: a grandparent that needs the event must receive it from the parent or from a service.
  • The event name string becomes a typed property, so the compiler finds every emitter and every listener.
  • event.stopPropagation() is no longer needed, because nothing travels further than the parent.

Migration tip. List each $emit event and who listens to it. If the listener is the direct parent, use an output; if it is several levels up, use a service declared in that ancestor's providers, which keeps the event limited to its subtree.

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