ThomasBurleson
3/24/2017 - 9:43 PM

Compare switchMap() to nested subscribe calls.

Compare switchMap() to nested subscribe calls.

import {Component, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {ContactsService} from '../contacts.service';
import {Contact} from '../models/contact';

import 'rxjs/add/operator/switchMap';
import {Subscription} from 'rxjs';

@Component({
  selector: 'trm-contacts-detail',
  templateUrl: './contacts-detail.component.html',
  styleUrls: ['./contacts-detail.component.css']
})
export class ContactsDetailComponent implements OnInit {
  subscription: Subscription;

  contact: Contact;

  constructor(private contactsService: ContactsService, private route: ActivatedRoute) {
  }

  /**
   *  BEST WAY!
   *  We need to subscribe to params changes because this component is
   *  reused when jumping between contacts. Hence ngOnInit isn't called
   */
  ngOnInit() {
    this.subscription = this.route.params
        .switchMap(params => this.contactsService.getContact(params['id']))
        .subscribe(contact => this.contact = contact);
  }

  /**
   * BAD WAY!
   * This is the traditional nested approach to chaining async stream events.
   * Notice the `clean()` function required to unsubscribe on errors and completion.
   */
  ngOnInit2() {
    this.subscription  = this.route.params.subscribe(params => {
      let clean = () => restSub.unsubscribe();
      let restSub = this.contactsService
                        .getContact(params['id'])
                        .subscribe(contact => {
                          this.contact = contact;
                          clean();
                        }, clean );
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

}