5 najczęstszych błędów podczas nauki Angulara

Temat bardzo ciekawy, a zarazem powielający pewne schematy. Zauważyłem, że nie ma znaczenia czy programista posiada juz jakieś doświadczenie czy nie, czy pisał na początku w Java Script, Javie lub C#. Dokonując obserwacji, wyciągając wnioski oraz tworząc pewną średnią okazało się, że jest 5 najczęściej popełnianych błędów poczas stawiania pierwszych kroków z Angularem.

Oczywiście tych problemów znaleźlibyśmy zapewne dużo więcej, natomiast chciałem przekazać 5 głównych. Jeżeli będziesz ich świadomy, to Twój kod wejdzie na wyższy poziom oraz będziesz zmierzał w kierunku kodu wysokiej jakości.

Przy omawianiu tych problemów zastosuję zasadę Pareto. W skrócie zasada Pareto mówi o tym, że 20% działań przenosi się na 80% sukcesów. Parafrazując: 5 problemów pokryje +/- 80% najczęściej spotykanych błędów.

1. Zapominanie o silnym typowaniu oraz właściwym nazewnictwie

Jeżeli miałbym podać jeden najczęściej występujący błąd, to wybrałbym właśnie ten. Widziałem to wielokrotnie oraz nadal zdarza mi się widzieć w nowych projektach.

O ile w przypadku programistów z zapleczem w takich językach jak Java czy C# ten problem nie wystepuje tak często, to w przypadku programistów którzy wywodzą się z Java Scriptu, ten problem pojawia się stosunkowo często.

Przy okazji tego błędu wielokrotnie pada stwierdzenie:

"Ale po co to dodawać skoro bez tego też działa."

Faktycznie jest to prawda, że bez silnego typowania aplikacja będzie działać, natomiast parafrazując słynne słowa Pana Wiesia:

Po to Angular wprowadza silne typowanie, żeby z niego korzystać.

Kod bez typowania

Kod z typowaniem

Podejście takie sprawia, że kod staje się bardziej czytelny. Na pierwszy rzut oka dokładnie widać, które części kodu są odpowiedzialne za co. Gdy wprowadzimy do kodu silne typowanie oraz zabdamy o odpowiednie nazewnictwo metod i zmiennych, znacznie zwiększy się jakość, czytelność oraz zrozumienie kodu.

2. Niewłaściwe wykorzystywanie cyklów życia komponentu

Angular udostępnia 8 cyklów życia komponentu. Chodzi tutaj o to, że pewne pewne sekwencje są wykonywane w określonej kolejności. Najczęściej spotykane i wykorzystywane są 3 główne cykle życia komponentu.

OnInit, OnChanges oraz OnDestroy.

  • OnInit: odpala się tylko raz podczas ustawienia dyrektyw widoku lub po przekazaniu zmiennych oznaczonych adnotacją @Input do komponentu.
  • OnChanges: odpala się za każdym razem gdy dojdzie do detekcji zmian np. na zmiennych oznaczonych adnotacją @Input.
  • OnDestroy: odpala się raz w chwili niszczenia komponentu.

Problem jaki się tutaj często pojawia, to inicjalizacja zmiennych w konstruktorze, zamiast w metodzie ngOnInit.

Błąd: inicjalizacja w konstruktorze komponentu

Poprawnie: inicjalizacja w metodzie ngOnInit komponentu

3. Brak odsubskrybowania od strumieni

Temat strumieni i programowania reaktywnego jest jednym z cięższych, gdy stykamy się z nim po raz pierwszy. Gdy opanujemy jego założenia i składnię okazuje się, że jest to potężne narzędzie, z którego nie chcemy rezygnować i zastanawiamy się jak mogliśmy, żyć bez korzystania z niego.

W tym artykule nie będziemy zgłębiać i tłumaczyć czym są strumienie i programowanie reaktywne, natomiast chciałbym abyś zapamiętał jedną podstawową zasadę: Od strumieni należy się odsubskrybować

Są przypadki i mechanizmy, które robią to automatycznie za Ciebie, natomiast jeżeli nie jesteś pewny czy powinieneś się odsubskrybować czy nie, to przyjmij sobie zasadę, że powinieneś.

Jeżeli okaże się, że mechanizmy Angulara zrobiły to za Ciebie a Ty i tak się odsubskrybowałeś, to nikomu nic złego się nie stanie. Gdy natomiast się okaże, że nie ma automatycznego odsubskrybowania, a Ty także tego nie zrobiłeś, dojdzie do wycieków pamięci, a tego wolelibyśmy uniknąć.

Destroyable na ratunek

Najczęściej spotykanym sposobem, jednym z bardziej eleganckich i reużywalnych, aby się od strumienia odsubskrybować, jest stworzenie nowej klasy o nazwie Destroyable.

Jest to prosty mechanizm, natomiast niezbędny, aby zapobiegać wyciekom pamięci. Subject destroyed$ jest ustawiany jako kompletny/zamknięty na metodzie ngOnDestroy.

Metoda ta wywoła się gdy komponent zostanie zniszczony, np. użytkownik przejdzie na inną zakładkę i komponent przestanie istnieć. W momencie gdy komponent zostanie zniszczony, odpali się właśnie metoda ngOnDestroy, a co za tym idzie gdy subject zostanie ustawiony jako complete, odpali się metoda takeUntil i subskrypcja na metodzie fetchAllCars zostanie odłączona.

Subscribe

Aby łatwiej było Ci zapamiętać oraz skojarzyć temat wyobraź sobie, że strumienie to nic innego jak strumień wody lecący z kranu.

Woda jest odkręcona (dokonana subskrypcja) gdy tego potrzebujemy.

Unsubscribe

Gdy skończysz myć ręce i chcesz opuścić łazienkę (moment niszczenia komponentu i skorzystanie z metody ngOnDestroy) zakręcasz kran z wodą.

Memory leak

Gdy wyjdziesz z łazienki i nie zakręcisz wody, może się okazać, ze gdy ponownie do niej wrócisz zastaniesz zalaną łazienkę, a nikt tego nie chce. (wyciek pamięci)

Obrazowe przedstawienie strumieni

Dokładniejszy opis czym są strumienie i jak je traktować znajdziesz w wideo poniżej.
Czas w wideo, w którym tłumaczę to zagadnienie: 22:34 - 25:00.

4. Wykorzystanie serwisu w szablonie

Ogólna zasada jest taka, że konstrukcje wstrzykiwane w konstruktorze w większości przypadków powinny być poprzedzone operatorem zasięgu private lub protected.

Spotykam się dosyć często z problemem, że programiści wstrzykują serwisy jako publiczne, co nie do końca jest poprawne Wszystko co w komponencie jest ustawione jako public będzie widoczne w szablonie.

Jako, że najczęściej w konstruktorze wstrzykuje się serwisy, nie powinny być one ustawiane jako public, ponieważ wykorzystanie serwisu w szablonie jest antypatternem i nie powinno się tego robić.

Jeżeli chcesz użyć zmiennej z serwisu w szablonie komponentu, to najlepszym rozwiązaniem będzie stworzenie publicznej zmiennej w komponencie a następnie przypisanie do tej zmiennej, zmiennej z serwisu. Następnie możesz wykorzystać taką zmienną w szablonie.

Przykładowy, uproszczony serwis

Błędny przykład

Poprawny przykład

5. Subskrypcja w serwisie

Taka sytuacja pojawia się równie często, jak poprzednie opisane błędy. Istnieje jedna prosta zasada, aby nie popełnić tego błędu.

Za każdym razem, gdy będziesz się zastanawiał czy dokonać subskrypcji w serwisie odpowiedź sam sobie, że nie.

W 99% przypadków nie powinieneś dokonywać subskrypcji w serwisie.

Jednym z nielicznych przypadków, gdy subskrypcja w serwisie jest dopuszczalna, to gdy będziesz implementował własny mechanizm popup/dialog. Praktycznie w każdym innym przypadku, nie powinieneś dokonywać subskrypcji w serwisie. Nie ważne, czy dokonujesz pobrania danych z backendu, czy chiałbyś pobrać dane z Subjectu, serwis nie jest warstwą, która powinna być odpowiedzialna za dokonywanie subskrypcji.

Idealnym miejscem do doknania subskrypcji jest szablon lub komponent.

Błędny przykład

Poprawny przykład

Podsumowanie:

Dodawaj typy zmiennych/obiektów, operatory widoczności jak public, private oraz typy zwracane z metod (void także)

Inicjalizacji danych w komponencie, dokonuj w metodzie ngOnInit, nie w konstruktorze

Od strumieni należy się odsubskrybować

Nie korzystaj bezpośrednio z serwisu w szablonie

Nie dokonuj subskrypcji w serwisie

Proponowane artykuły:

Proces: Etap 5/5
Poprzedni artykuł
10 dobrych praktyk
Kolejny artykuł

Zapisz się na newsletter. Otrzymuj najnowsze artykuły.