Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@mindspace-io/rxjs-utils

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mindspace-io/rxjs-utils

## Purpose

  • 1.0.0-beta.4
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
1
Maintainers
1
Weekly downloads
 
Created
Source

Mindspace RxJS Utilities

Purpose

This library provides utilities to auto-unsubscribe [from a RxJS stream subscription] when a view component is destroyed. While originally written for Angular developers, some of the utilities can be used with any JS + RxJS implementation.

  • untilViewDestroyed(<ElementRef> | <Component>): RxJS operator to auto-unsubscribe when the Angular view instance is destroyed.

  • autoUnsubscribe(<Subscription>,<HtmlElement>): clear the specified subscription when the target DOM element is removed from its parent DOM container.

  • watchElementDestroyed(<HtmlElement>): watch target DOM element and emit true when destroyed.

  • watchViewDestroyed(<Component>): watch target Angular Component ngOnDestroy() is called and will emit true.

Using @mindspace-io/rxjs-utils

The untilViewDestroyed() RxJS operator is the most commonly used feature. Review the code sample below on how to auto-unsubscribe an Angular View component after ngOnDestroy() or when the element is removed from its DOM container.

import {untilViewDestroyed} from '@mindspace-io/rxjs-utils';
   
@Component({})   
export class TicketDetails implements OnInit, OnDestroy {  
 tickets: string[];
 search: FormControl;  

 constructor(private ticketService: TicketService){}

 ngOnInit() {   
   const findTickets = (criteria:string) => this.ticketService.findAll(criteria);
  
   this.search.valueChanges.pipe(  
     untilViewDestroyed(this),  
     switchMap(findTickets), 
     map(ticket=> ticket.name)  
   )   
   .subscribe( tickets => this.tickets = tickets ); 
 } 

 ngOnDestroy() { }
 
}

This is a contrived example that does not itself use the power of the async pipe.

Nevertheless, developers will encounter other scenarios that require manual subscriptions and subscription management. And then untilViewDestroyed() becomes a very useful RxJS operator.



Live Demo

image




Typical Angular RxJS Subscription Leak

Consider the following DocumentViewerComponent which uses a service to load a list of documents. availableDocuments$` is a RxJS stream which will asynchronously emit/deliver the document list WHENEVER it is available or changes.

This implementation has a memory leak because the subscription is long-lived and is not managed!

@Component({
  selector: 'document-viewer',
  template: `
    <h1>Documents for {{fullName}}</h1>
    <document-list [dataProvider]="documents">
    </document-list>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DocumentViewerComponent implements OnInit, OnDestroy {  
  @Input() fullName: string;
  documents: Documents[];

  constructor(
    private service: MyService,
    private cd: ChangeDetectorRef,
  ) {}

  ngOnInit(): void {
    this.service.availableDocuments$.subscribe(list => {
      this.documents = list;
      this.cd.markForCheck();
    });
  }
    
  ngOnDestroy() { }
}



Bad Solution #1: Using ngOnDestroy()

Here is the typical implementation [using ngOnDestroy() + takeUntil()] to manage such RxJS subscriptions:

@Component({...})
export class DocumentViewerComponent implements OnInit {  
  @Input() fullName: string;
  documents: Documents[];

  constructor(
    private service: MyService,
    private cd: ChangeDetectorRef,
  ) {}

  ngOnDestroy(): void {
    this._subscription.unsubscribe();
  }

  ngOnInit(): void {
    this._subscription = this.service.availableDocuments$.subscribe(list => {
      this.documents = list;
      this.cd.markForCheck();
    });
  }

  private _subscription: Subscription;
}

Bad Solution #2: Using a notification Subject

@Component({...})
export class DocumentViewerComponent implements OnInit {  
  @Input() fullName: string;
  documents: Documents[];

  constructor(
    private service: MyService,
    private cd: ChangeDetectorRef,
  ) {}

  ngOnDestroy(): void {
    this._notifier.next();
    this._notifier.complete();
  }

  ngOnInit(): void {
    this.service.availableDocuments$.pipe(
      takeUntil(this._notifier.asObservable())
    ).subscribe(list => {
      this.documents = list;
      this.cd.markForCheck();
    });
  }

  private _notifier = new Subject<void>();
}

Notice how this both of these approaches require extra view logic simply to using the OnDestroy lifecycle event to auto-unsubscribe. And when trying to manage multiple subscriptions in a single component, these approaches require code that significantly pollutes your view implementation.

To avoid view-code cruft, use the @mindspace/rxjs-utils!

FAQs

Package last updated on 21 Jun 2019

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc