typescript - from - rxjs observable angular 6
ObjectUnsubscribedError al intentar evitar suscribirse dos veces (2)
.subscribe () devuelve una Suscripción
- Usted debe usar esto para darse de baja
por ejemplo, Parent tiene un reloadSubject: Subject;
- child1 -> se suscribe
- child2 -> se suscribe
child1 - "WORKS" -> unsubscribe''s su suscripción
ngOnInit{
sub: Subscription = parent.subscribe();
}
onDestroy{
this.sub.unsubscribe();
}
child2 - "NO FUNCIONA" -> cancelar la suscripción a todo el padre
ngOnInit{
parent.subscribe();
}
onDestroy{
parent.unsubscribe();
}
Si llama a cancelar la suscripción en el padre, ambos hijos se han ido.
Si cancela la suscripción de la suscripción que obtiene de .subscribe (), solo se desuscribe un hijo.
¡Por favor, corríjame si estoy equivocado!
Tengo un servicio y un componente que lo usa:
PagesService
-
PagesListComponent
En el PagesService
de Pages
tengo una matriz de Pages
. Notifico cambios en la matriz a través de un BehaviorSubject
que están suscritos ambos.
El servicio PagesService
se proporciona en bootstrap
, para tener solo una instancia compartida. Eso es porque necesito mantener la matriz, en lugar de descargar las páginas cada vez que se necesitan.
El código es el siguiente:
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>) {
// Parses de Array<any> and creates 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();
}
}
Esto funciona bien la primera vez, tanto la suscripción onInit como la desuscripción onDestroy. Pero cuando vuelvo a la lista e intento suscribirme de nuevo (para obtener el valor actual de las páginas [] y escuchar los cambios futuros), se dispara el error EXCEPTION: ObjectUnsubscribedError
.
Si no me doy de baja, cada vez que entro en la lista, se apila una nueva suscripción, y todas se activan cuando se recibe un next ().
Obtendría la suscripción y me doy de baja de esta manera y no directamente sobre el tema:
ngOnInit() {
this.pages$ = this.pagesService.getPagesListener();
this.subscription = this.pages$.subscribe((pages) => { // <-------
this.pages = pages; console.log(pages);
});
this.pagesService.getAll();
}
ngOnDestroy() {
this.subscription.unsubscribe(); // <-------
}