Rxjs Observable Lifecycle


If I am ever working with rxjs, I normally, in my component file, keep track of all of my subscriptions by pushing said subscriptions into a Subscription array:

private subcriptions: Subscription[]; this.subscriptions.push(this.myObservableOne.subscribe(...)); this.subscriptions.push(this.myObservableTwo.subscribe(...)); public ngOnDestroy(): void { this.subscriptions.forEach(s => s.unsubscribe()); }

Now, I am running into something that I thought was interesting. If I instead need to subscribe to an Observable from a service:


Who owns the subscription? Will my component own it, or will the service own it? In other words, will my service need to implement ngOnDestroy to unsubscribe from that Observable?

I feel like doing: this.subscriptions.push(this.myService.myObservable.subscribe(...)); might work but I am not entirely sure.


Calling .subscribe(...) on an <em>Observable</em> returns a <em>Subscription</em>.

If you don't assign this subscription to a variable (or in your case push it to an array of subscriptions), you will lose reference to this subscription, hence you can't unsubscribe from it, which can cause memory leaks.

So your assumption of pushing it into array of subscriptions:


and unsubscribing in <em>ngOnDestroy</em> of your component is correct.


Another option is to use takeWhile or something similar with a flag such as the componentActive flag below. Something like the code shown below.

This completes the subscription so you don't need to unsubscribe.

import { Component, OnInit, OnDestroy } from '@angular/core'; import { Product } from '../product'; import { Observable } from 'rxjs'; import { takeWhile } from 'rxjs/operators'; /* NgRx */ import { Store, select } from '@ngrx/store'; @Component({ selector: 'pm-product-list', templateUrl: './product-list.component.html', styleUrls: ['./product-list.component.css'] }) export class ProductListComponent implements OnInit, OnDestroy { componentActive = true; // Used to highlight the selected product in the list selectedProduct: Product | null; constructor(private store: Store<fromProduct.State>) { } ngOnInit(): void { // Subscribe here because it does not use an async pipe this.store.pipe( select(fromProduct.getCurrentProduct), takeWhile(() => this.componentActive) ).subscribe( currentProduct => this.selectedProduct = currentProduct ); } ngOnDestroy(): void { this.componentActive = false; } }


  • Where to place setContentView() in onCreate()?
  • Table style border- outlook 2010 adds an extra space
  • How to get OEM USB driver for Samsung Galaxy SIII with model number GT-I9300
  • How to reproduce the layout of the Windows 10 settings window in QML?
  • Updating multiple columns with data from subquery in MySQL
  • find in a javascript array from meteor mongodb
  • Can we implement some code that fires upon selecting something in google document?
  • Import named range data between Google Workbooks
  • Improving Cython Lapack performance with internal array definitions?
  • Creating an Array of values from DB and passing into a Form
  • Footer bottom of the screen
  • Google Spreadsheets Copy Value and Formats Script Issues
  • iText parser exception for XML -> PDF conversion
  • Symfony authentication with LDAP
  • Paypal IPN Listener Issue in C#
  • Canvas: Trying to use a recycled bitmap error
  • How to save a image coded in Data-URI?
  • Add a new custom default ordering catalog option in Woocommerce
  • How to get data from activation link with Java Servlet
  • HTTPS request/response in Android
  • Problem with output_buffering and php.ini
  • PostgreSQL in Docker - pg_hba.conf to allow access from host to container
  • Raphael-GWT: fill image of a shape (Rect) appears offset. How to resolve this?
  • configure openjpa on to spring boot
  • Magento Layered Navigation block. Move to center
  • Bulk loading into PostgreSQL from a remote client
  • MayAVI install on Python 3.6 [duplicate]
  • Multiple canvases (pages) in Fabric.js
  • How to display content depending on dropdown menue user selection
  • Find all parks for a given zipcode with google maps
  • content must have a ListView whose id attribute is 'android.R.id.list'
  • How to create subsets of a single set of elements with XSLT?
  • Creating 2d platforms using JavaScript
  • Ruby regex for matching simpliest Ruby's regexes
  • How to write seo friendly url's using htaccess?
  • Is there a better way for handling SpatialPolygons that cross the antimeridian (date line)?
  • How to make 100% div height between header and footer?
  • How to integrate angular2-material (alpha 8.2) with angular2-Quickstart app
  • Why does Rails 3 think xE2x80x89 means â x80 x89
  • How to check if object is null in Java?