:sparkles: PWA :sparkles:
Logo

Piotr Kowalski

Organizator WarsawJS , Trener, YouTuber

Angular: Krótka historia o tym jak złamałem system

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.

Dajcie znać, czy taka forma artykułów Wam pasuje :question:

Tagi: javascript typescript angular

2 tygodnie i 6 dni wcześniej napisałem: Vue.js na Heroku 1 miesiąc i 1 tydzień później napisałem: Hackathon: Node Knockout #7 (2017)

Możesz osadzić kod wykorzystując: <pre><code class="{language}"></code></pre>