Lubię krótkie wpisy. Tylko nie umiem ich pisać. Stąd też rzadko publikuję, bo wyobrażam sobie te wielogodzinne poświęcenie, aby napisać WSPANIAŁY, a zaraz długi artykułu traktującego o zadanym temacie…
Muszę nauczyć się pisać zwięźle i z mięsem. Sam lubię czytać takie rzeczy, więc czytelnicy tego bloga zapewne również. Do rzeczy.
Problem
Jest sobie taki serwis:
@Injectable()
export class UserPurchasesStateManagerService {
private purchasesState$ = new BehaviorSubject(...);
public setPurchasesState(state: number): void {
this.purchasesState$.next(state);
}
public getPurchasesState$(): BehaviorSubject<number> {
return this.purchasesState$;
}
}
Niby wszystko poprawnie, ale errrr…
Wystarczy, że po utworzeniu instancji serwisu (przypominam, że w Angularze instancje serwisów są singletonami) zrobię tak:
// Sztuczne tworzenie, oczywiście Angular zrobi to niejawnie
const stateManager = new UserPurchasesStateManagerService();
// Boom!!
stateManager.getPurchasesState$().next(null);
…i złamałem system ☹️
Solucja
Trzeba zmienić definicję (i sygnaturę) gettera na:
// ...
export class UserPurchasesStateManagerService {
// ...
public getPurchasesState$(): Observable<number> {
return this.purchasesState$.asObservable();
}
}
A teraz krótka porada:
Porada
Jeśli gdzieś chcemy zwrócić subject-a to lepiej zrobić tak:
- ukryć do private-em
- zrobić getter, który go zwróci ale przekształci za pomocą
.asObservable()
w strumieńread-only
inaczej oddamy władzie zmiany stanu komuś innemu.