title: Why does the async pipe continue to emit values after an error?
body: <p>I have come upon a difference between using the async pipe and subscribing to an observable manually in a template which I have not yet seen in any article discussing differences between these approaches.</p>
  <p>Let's say I have a component with an observable which listens to a reload subject (<code>@Input() reload = new ReplaySubject&lt;void&gt;(1)</code>), which emits upon route change, to refetch its data from a server and, for the sake of the example, doesn't ever get destroyed - e.g. a detail component which parent is a listing of all detail components.</p>
  <p>First, using the subscribe() method, if the fetch request errors out, the observable the method subscribed to, errors out as well and thus completes and stops emitting values. That is expected. If I were to change the route to a different detail, the reload subject emits, but the components observable is completed, so it doesn't perform any logic:</p>
  <pre><code>  @Input() public refresh: Observable&lt;void&gt;;
    private refreshInternal = new ReplaySubject&lt;GridViewParams&gt;(1);
    public refreshInternalObs = this.refreshInternal.asObservable();
  
    private initializeInternalRefreshListener(): void {
      this.refreshInternalObs
        .pipe(
          switchMap(() =&gt; this.httpRequest()),
          takeUntil(this.unsubscriber),
          finalize(() =&gt; {
            // fires once after request error
            // observable then completes
            // and no logic ever fires again
          })
        )
        .subscribe(() =&gt; {
          // this code is never reached after obervable errors out once
        });
    }
  
    private initializeExternalRefreshListener(): void {
      this.refresh.pipe(takeUntil(this.unsubscriber)).subscribe(
        () =&gt; {
          // fires every time a notification is sent from parent, 
          // even after refreshInterval is completed
          this.refreshInternal.next();
        },
      );
    }
  </code></pre>
  <p>However, when I use the async pipe method instead, switching routes after error gets fetches new values as if the async pipe subscribed again after the observable erroring out.</p>
  <pre><code>&lt;!-- gets new data every time even after refreshInternal erroring out --&gt;
  &lt;ng-container *ngIf=&quot;this.refreshInternalObs | async as data&quot;&gt;{{ data | json }}&lt;/ng-container&gt;
  </code></pre>
  <p>...</p>
  <pre><code>  @Input() public refresh: Observable&lt;void&gt;;
    private refreshInternal = new ReplaySubject&lt;GridViewParams&gt;(1);
    public refreshInternalObs = this.refreshInternal.asObservable();
  
    private initializeInternalRefreshListener(): void {
      // seems to not get completed after erroring out
      this.refreshInternalObs
        .pipe(
          switchMap(() =&gt; this.httpRequest()),
        )
    }
  
    private initializeExternalRefreshListener(): void {
      this.refresh.pipe(takeUntil(this.unsubscriber)).subscribe(
        () =&gt; {
          // fires every time a notification is sent from parent, 
          this.refreshInternal.next();
        },
      );
    }
  </code></pre>
  <p>How did the async pipe do that? Is it because the changeDetection (using the default one) resubscribes to the async pipe every cycle? Or does the async pipe use some kind of &quot;retry&quot; logic?</p>