I am dealing with a Service and a component that utilizes it:
PagesService
PagesListComponent
Within the PagesService
, there exists an array of Pages
. Updates to this array are communicated via a BehaviorSubject
that both components subscribe to.
The PagesService
is provided at bootstrap
in order to have a single shared instance. This is necessary to maintain the array without having to download pages every time they are needed.
The code setup is as follows:
pages.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/Rx';
import { Http, Response } from '@angular/http';
import { Page } from './../models/page';
@Injectable() export class PagesService {
public pages$: BehaviorSubject<Page[]> = new BehaviorSubject<Page[]>([]);
private pages: Page[] = [];
constructor(private http: Http) { }
getPagesListener() {
return this.pages$;
}
getAll() {
this.http.get('/mockups/pages.json').map((res: Response) => res.json()).subscribe(
res => { this.resetPagesFromJson(res); },
err => { console.log('Pages could not be fetched'); }
);
}
private resetPagesFromJson(pagesArr: Array<any>) {
// Parsing the Array<any> and creating an Array<Page>
this.pages$.next(this.pages);
}
}
pages_list.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router-deprecated';
import { BehaviorSubject } from 'rxjs/Rx';
import { PagesService } from '../../shared/services/pages.service';
import { GoPage } from '../../shared/models/page';
@Component({
moduleId: module.id,
selector: 'go-pages-list',
templateUrl: 'pages_list.component.html',
styleUrls: ['pages_list.component.css']
})
export class PagesListComponent implements OnInit {
pages$: BehaviorSubject<GoPage[]>;
pages: GoPage[];
constructor(private pagesService: PagesService, private router: Router) { }
ngOnInit() {
this.pages$ = this.pagesService.getPagesListener();
this.pages$.subscribe((pages) => { this.pages = pages; console.log(pages) });
this.pagesService.getAll();
}
ngOnDestroy() {
this.pages$.unsubscribe();
}
}
This implementation works well initially, with subscription onInit and unsubscription onDestroy. However, upon attempting to re-subscribe when returning to the list (to fetch the current value of pages[] and listen for future changes), it results in an error being thrown -
EXCEPTION: ObjectUnsubscribedError
.
If I omit the unsubscribe method, a new subscription is stacked each time I enter the list, causing all of them to trigger when next() is received.