Angular Finalize Change Detection

Viewed 164

I have the following defined in my component's HTML:

<button mat-button type="submit" [disabled]="invalidEmail" [ladda]="isLoading">Reset Password</button>

Where the [ladda] is a custom directive that shows a loading icon on the button when the respective variable is true; in this case the variable is named isLoading. Generally I'm doing this when hitting the server, so I will set isLoading to true before I hit the server and then set it to false when the response is returned.

Where this gets a little hairy is when I try to use an rxjs pipe/finalize pattern. If I run the following, the change is never detected:

this.passwordService.resetPassword(input)
    .pipe(finalize(() => this.isLoading = false))
    .subscribe(
        () => this.success = true,
        err => this.error = JSON.stringify(err)
    );

I have to manually call NgZone::run in order for it to work:

this.passwordService.resetPassword(input)
    .pipe(finalize(() => this.ngZone.run(() => this.isLoading = false)))
    .subscribe(
        () => this.success = true,
        err => this.error = JSON.stringify(err)
    );

Why is this, am I doing this wrong?

update - per request, here is the resetPassword method:

resetPassword(reset: IPasswordReset): Observable<void> {
    const url = `${environment.ApiUrl}/Api/UserProfile/ResetPasswordFromToken`;
    const options = new HttpOptions();
    options.headers = new HttpHeaders();
    options.headers = options.headers.append('Content-Type', 'application/x-www-form-urlencoded');
    return this.http.post(url, reset, null, options);
}
1 Answers

Have you tried the complete method?

this.passwordService.resetPassword(input)
    .subscribe(
        () => this.success = true,
        err => this.error = JSON.stringify(err),
        () => this.isLoading = false
    );
Related