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.
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
Zapisz się na newsletter. Otrzymuj najnowsze artykuły.