HI WELCOME TO SIRIS

Angular observable unsubscribe

Leave a Comment

Let us understand this with an example. Here is what we want to do. When the request to the server is in progress we want to display "Cancel Request" button.

Angular observable unsubscribe


The "Cancel Request" button should only be visible to the user when there is a request in progress. When the request fails permanently after exhausting all the retry attempts the button should disappear. 
observable unsubscribe example

Along the same lines if the request completes successfully, then also the button should disappear.
how to unsubscribe from observable angular 2

When the user cancels the request, by clicking the "Cancel Request" button, the request should be cancelled and button should disappear.
angular cancel observable

To achieve this, include the following HTML in employee.component.html file. This HTML is for the "Cancel Request" button. Please pay attention to the structural directive ngIf on the <div> element that contains the button. As you can see we are showing the "Cancel Request" button only if the subscription is not closed (!subscription.closed), meaning only when there is a request to the Observable is in progress. 

The ngIf directive will take care of showing and hiding the <div> element depending on whether the subscription is closed or not. We are also binding the click event of the button to "onCancelButtonClick()" method. We will create both the subscription object and the "onCancelButtonClick()" method in the component class.

<div style="margin-top:5px" *ngIf="!subscription.closed">
    <input type="button" class="btn btn-primary" value="Cancel Request"
           (click)="onCancelButtonClick()" />
</div>

Now modify the code in employee.component.ts file as shown below. The relavant code is commented and self-explanatory.

import { Component, OnInit } from '@angular/core';
import { IEmployee } from './employee';
import { EmployeeService } from './employee.service';
import { ActivatedRoute } from '@angular/router';
import { Router } from '@angular/router';

import 'rxjs/add/operator/retrywhen';
import 'rxjs/add/operator/delay';
import 'rxjs/add/operator/scan';
// import ISubscription.
import { ISubscription } from "rxjs/Subscription";

@Component({
    selector: 'my-employee',
    templateUrl: 'app/employee/employee.component.html',
    styleUrls: ['app/employee/employee.component.css']
})
export class EmployeeComponent implements OnInit {
    employee: IEmployee;
    statusMessage: string = 'Loading data. Please wait...';
    retryCount: number = 1;

    // Create a class property of type ISubscription
    // The ISubscription interface has closed property
    // The ngIf directive in the HTML binds to this property
    // Go to the difinition of ISubscription interface to
    // see the closed property
    subscription: ISubscription;

    constructor(private _employeeService: EmployeeService,
        private _activatedRoute: ActivatedRoute,
        private _router: Router) { }

    ngOnInit() {
        let empCode: string = this._activatedRoute.snapshot.params['code'];

        // Use the subscription property created above to hold on to the
        // subscription.We use this object in the onCancelButtonClick()
        // method to unsubscribe and cancel the request
        this.subscription = this._employeeService.getEmployeeByCode(empCode)
            .retryWhen((err) => {
                return err.scan((retryCount, val) => {
                    retryCount += 1;
                    if (retryCount < 4) {
                        this.statusMessage = 'Retrying...Attempt #' + retryCount;
                        return retryCount;
                    }
                    else {
                        throw (err);
                    }
                }, 0).delay(1000)
            })
            .subscribe((employeeData) => {
                if (employeeData == null) {
                    this.statusMessage =
                        'Employee with the specified Employee Code does not exist';
                }
                else {
                    this.employee = employeeData;
                }
            },
            (error) => {
                this.statusMessage =
                    'Problem with the service. Please try again after sometime';
                console.error(error);
            });
    }

    onBackButtonClick(): void {
        this._router.navigate(['/employees']);
    }

    // This method is bound to the click event of the "Cancel Request" button
    // Notice we are using the unsubscribe() method of the subscription object
    // to unsubscribe from the observable to cancel the request. We are also
    // setting the status message property of the class to "Request Cancelled"
    // This message is displayed to the user to indicate that the request is cancelled
    onCancelButtonClick(): void {
        this.statusMessage = 'Request cancelled';
        this.subscription.unsubscribe();
    }
}

0 comments:

Post a Comment

Note: only a member of this blog may post a comment.