4

I'm reading through this tutorial on integrating stripe elements with Angular and I'm just curious as to why the onChange method calls detectChanges() at the end. The onChange method is added as an event listener to the stripe card and will assign an error if onChange receives one.

onChange({ error }) {
  if (error) {
    this.error = error.message;
  } else {
    this.error = null;
  }
  this.cd.detectChanges();
}
Ole
  • 41,793
  • 59
  • 191
  • 359

2 Answers2

1

I guess it related from Angular Change Detection Strategy.

Default strategy will check the view every time a event is propagated in component (mouse, click, input, XHR, etc). This strategy is not adapted on complex application because performance can be terrible.

An alternative is to use OnPush strategy. This strategy will rerender the view only when @Input have changed or when you explicitly ask to detect change with ChangeDetectorRef.detectChanges();

Martin Choraine
  • 2,296
  • 3
  • 20
  • 37
1

Stripe (and some other 3rd party) run outside of angular's zone, then we need to use ChangeDetectorRef. Another option to use is also NgZone. Got a bit curious myself on how Stripe works outside of Angular zone, since the reasons can vary. For Stripe specifically, according to this

The Angular Zones are monkey patching (almost) all asynchronous APIs! Zones intercept async events and triggering the change detection on special events. Zones take care of XMLHttpRequests, fetch, setTimeout, etc. However, Stripe uses hidden iframe for establishing requests to its API, instead of the APIs that zone.js takes care of.

Some further reading on zones and change detection and difference between NgZone and ChangeDetectorRef.

AT82
  • 71,416
  • 24
  • 140
  • 167
  • Thanks - Great answer - It should be the accepted one - but I'm leaving it as is since Martin could use the points. – Ole Aug 04 '19 at 19:59
  • 1
    No problem, my curiosity is satisfied so that's fine :P – AT82 Aug 05 '19 at 13:18