From 6f1a42373dc03c01a281f78bf2167765ec707c85 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Wed, 22 Jul 2020 13:04:27 +0300 Subject: [PATCH] docs: explain how the subscription service works --- docs/en/UI/Angular/Subscription-Service.md | 203 +++++++++++++++++++++ docs/en/UI/Angular/Track-By-Service.md | 2 +- docs/en/docs-nav.json | 4 + 3 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 docs/en/UI/Angular/Subscription-Service.md diff --git a/docs/en/UI/Angular/Subscription-Service.md b/docs/en/UI/Angular/Subscription-Service.md new file mode 100644 index 0000000000..b92cd26c59 --- /dev/null +++ b/docs/en/UI/Angular/Subscription-Service.md @@ -0,0 +1,203 @@ +# Easy Unsubscription for Your Observables + +`SubscriptionService` is a utility service to provide an easy unsubscription from RxJS observables in Angular components and directives. Please see [why you should unsubscribe from observables on instance destruction](https://angular.io/guide/lifecycle-hooks#cleaning-up-on-instance-destruction). + +## Getting Started + +You have to provide the `SubscriptionService` at component or directive level, because it is **not provided in root** and it works in sync with component/directive lifecycle. Only after then you can inject and start using it. + +```js +import { SubscriptionService } from '@abp/ng.core'; + +@Component({ + /* class metadata here */ + providers: [SubscriptionService], +}) +class DemoComponent { + count$ = interval(1000); + + constructor(private subscription: SubscriptionService) { + this.subscription.subscribe(this.count$, console.log); + } +} +``` + +The values emitted by the `count$` will be logged until the component is destroyed. You will not have to `unsubscribe` manually. + +> Please do not try to use a singleton `SubscriptionService`. It simply will not work. + +## Usage + +### How to Subscribe to Observables + +You can pass a `next` function and an `error` function. + +```js +@Component({ + /* class metadata here */ + providers: [SubscriptionService], +}) +class DemoComponent implements OnInit { + constructor(private subscription: SubscriptionService) {} + + ngOnInit() { + const source$ = interval(1000); + const nextFn = value => console.log(value * 2); + const errorFn = error => { + console.error(error); + return of(null); + }; + + this.subscription.subscribe(source$, nextFn, errorFn); + } +} +``` + +Or, you can pass an observer. + +```js +@Component({ + /* class metadata here */ + providers: [SubscriptionService], +}) +class DemoComponent implements OnInit { + constructor(private subscription: SubscriptionService) {} + + ngOnInit() { + const source$ = interval(1000); + const observer = { + next: value => console.log(value * 2), + complete: () => console.log('DONE'), + }; + + this.subscription.subscribe(source$, observer); + } +} +``` + +Ths `subscribe` method returns the individual subscription, so that you may use it later on. Please see topics below for details. + +### How to Unsubscribe Before Instance Destruction + +There are two ways to do that. If you are not going to subscribe again, you may use the `unsubscribeAll` method. + +```js +@Component({ + /* class metadata here */ + providers: [SubscriptionService], +}) +class DemoComponent implements OnInit { + constructor(private subscription: SubscriptionService) {} + + ngOnInit() { + this.subscription.subscribe(interval(1000), console.log); + } + + onSomeEvent() { + this.subscription.unsubscribeAll(); + } +} +``` + +This will clear all subscriptions, but you will not be able to subscribe again. If you are planning to add another subscription, you may use the `reset` method instead. + +```js +@Component({ + /* class metadata here */ + providers: [SubscriptionService], +}) +class DemoComponent implements OnInit { + constructor(private subscription: SubscriptionService) {} + + ngOnInit() { + this.subscription.subscribe(interval(1000), console.log); + } + + onSomeEvent() { + this.subscription.reset(); + this.subscription.subscribe(interval(1000), console.warn); + } +} +``` + +### How to Unsubscribe From a Single Subscription + +Sometimes, you may need to unsubscribe from a particular subscription but leave others alive. In such a case, you may use the `unsubscribeOne` method. + +```js +@Component({ + /* class metadata here */ + providers: [SubscriptionService], +}) +class DemoComponent implements OnInit { + countSubscription: Subscription; + + constructor(private subscription: SubscriptionService) {} + + ngOnInit() { + this.countSubscription = this.subscription.subscribe( + interval(1000), + console.log + ); + } + + onSomeEvent() { + this.subscription.unsubscribeOne(this.countSubscription); + console.log(this.countSubscription.closed); // true + } +} +``` + +### How to Remove a Single Subscription From Tracked Subscriptions + +You may want to take control of a particular subscription. In such a case, you may use the `removeOne` method to remove it from tracked subscriptions. + +```js +@Component({ + /* class metadata here */ + providers: [SubscriptionService], +}) +class DemoComponent implements OnInit { + countSubscription: Subscription; + + constructor(private subscription: SubscriptionService) {} + + ngOnInit() { + this.countSubscription = this.subscription.subscribe( + interval(1000), + console.log + ); + } + + onSomeEvent() { + this.subscription.removeOne(this.countSubscription); + console.log(this.countSubscription.closed); // false + } +} +``` + +### How to Check If Unsubscribed From All + +Please use `isClosed` getter to check if `unsubscribeAll` was called before. + +```js +@Component({ + /* class metadata here */ + providers: [SubscriptionService], +}) +class DemoComponent implements OnInit { + constructor(private subscription: SubscriptionService) {} + + ngOnInit() { + this.subscription.subscribe(interval(1000), console.log); + } + + onSomeEvent() { + console.log(this.subscription.isClosed); // false + } +} +``` + +## What's Next? + +- [ListService](./List-Service.md) diff --git a/docs/en/UI/Angular/Track-By-Service.md b/docs/en/UI/Angular/Track-By-Service.md index 447cc4505a..050706accd 100644 --- a/docs/en/UI/Angular/Track-By-Service.md +++ b/docs/en/UI/Angular/Track-By-Service.md @@ -116,4 +116,4 @@ class DemoComponent { ## What's Next? -- [ListService](./List-Service.md) +- [SubscriptionService](./Subscription-Service.md) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index a6ab09dfee..85f1567406 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -434,6 +434,10 @@ "text": "TrackByService", "path": "UI/Angular/Track-By-Service.md" }, + { + "text": "SubscriptionService", + "path": "UI/Angular/Subscription-Service.md" + }, { "text": "ListService", "path": "UI/Angular/List-Service.md"