[{"data":1,"prerenderedAt":300},["ShallowReactive",2],{"project-\u002Fpl\u002Fprojekty\u002F2024\u002Fpokedex":3,"project-posts-\u002Fpl\u002Fprojekty\u002F2024\u002Fpokedex":134},{"id":4,"title":5,"agency":6,"body":7,"compare":6,"cover":72,"date":78,"description":79,"draft":80,"extension":81,"facts":82,"featured":80,"gallery":96,"galleryLead":6,"highlights":6,"image":112,"links":113,"meta":116,"navigation":117,"note":6,"ogImage":118,"path":119,"seo":120,"stack":121,"stem":127,"tags":128,"__hash__":133},"projects_pl\u002Fpl\u002Fprojekty\u002F2024\u002Fpokedex\u002Findex.md","Pokedex",null,{"type":8,"value":9,"toc":67},"minimark",[10,14,19],[11,12,13],"p",{},"Pokedex to mój pierwszy większy projekt w JavaScripcie. Pisałem go równolegle z kursem i chciałem zrobić coś trudniejszego niż kolejną listę zadań. Wyszła interaktywna encyklopedia ponad 1000 pokemonów – w czystym JavaScripcie (ES6+, wzorce OOP), bez frameworków, na publicznym PokéAPI. W trakcie co chwilę wpadałem na nowe pomysły – złapane pokemony, eksport między przeglądarkami, motywy – i nie zawsze kończyłem jeden, zanim zacząłem następny. Dlatego zrobiłem listę i zacząłem wdrażać zmiany etapami – każdy nowy pomysł trafiał na listę „do zrobienia”, zamiast odciągać mnie od tego, co akurat robiłem.",[15,16,18],"h2",{"id":17},"najważniejsze-cechy","Najważniejsze cechy",[20,21,22,30,41,58,61,64],"ul",{},[23,24,25,26],"li",{},"Przemyślana kolejność ładowania danych z PokéAPI – równoległe zapytania przez ",[27,28,29],"code",{},"Promise.all",[23,31,32,33,36,37,40],{},"Lokalna baza w przeglądarce (",[27,34,35],{},"LocalStorage"," + ",[27,38,39],{},"SessionStorage",") – raz pobrane dane nie idą drugi raz do API",[23,42,43,44,47,48,47,51,47,54,57],{},"Modułowa architektura klas (",[27,45,46],{},"DataManager",", ",[27,49,50],{},"DataBuilder",[27,52,53],{},"StorageManager",[27,55,56],{},"PokemonDialog",") przygotowana pod migrację do Vue 3",[23,59,60],{},"Responsywna, dwukierunkowo synchronizowana paginacja z odwzorowaniem stanu w URL",[23,62,63],{},"Jasny i ciemny motyw (też automatyczny, według ustawień systemu)",[23,65,66],{},"Złapane pokemony – zaznaczanie w karcie pokemona, import i eksport listy w ustawieniach",{"title":68,"searchDepth":69,"depth":69,"links":70},"",2,[71],{"id":17,"depth":69,"text":18},{"desktop":73,"phone":74,"width":75,"height":76,"alt":77},"\u002Fprojects\u002F2024\u002Fpokedex\u002Flist.webp","\u002Fprojects\u002F2024\u002Fpokedex\u002Fphone.webp",1920,1105,"Pokedex – lista pokemonów z paginacją","2024-01-28","Interaktywny Pokedex na ponad 1000 pokemonów w czystym JavaScript (OOP), oparty o PokéAPI – z przemyślaną kolejnością ładowania danych i lokalną bazą w przeglądarce.",false,"md",[83,86,89,93],{"value":84,"text":85},"2024","rok realizacji",{"value":87,"text":88},"Solo","projekt własny – od pomysłu po wdrożenie",{"value":90,"suffix":91,"text":92},"1000","+","pokemonów z PokéAPI – kilkadziesiąt zapytań zamiast ponad 1000",{"value":94,"text":95},"Vanilla JS","bez Vue, Reacta i innych frameworków – własne klasy w czystym JavaScript",[97,100,104,108],{"src":73,"width":75,"height":76,"alt":98,"caption":99},"Lista pokemonów z paginacją","Lista – ponad 1000 pokemonów, numer strony zapisany w adresie (?p=)",{"src":74,"device":101,"alt":102,"caption":103},"phone","Pokedex na telefonie – karta pokemona","Telefon – karta pokemona otwarta nad listą w dwóch kolumnach",{"src":105,"width":75,"height":76,"alt":106,"caption":107},"\u002Fprojects\u002F2024\u002Fpokedex\u002Fpokemon-card.webp","Okno szczegółów pokemona","Karta pokemona – nazwa, typy i generacja od razu z pamięci, statystyki dociągane z API",{"src":109,"width":75,"height":76,"alt":110,"caption":111},"\u002Fprojects\u002F2024\u002Fpokedex\u002Fsettings.webp","Ustawienia aplikacji","Ustawienia – motyw, import i eksport złapanych pokemonów, czyszczenie danych","\u002Fprojects\u002F2024\u002Fpokedex\u002Fthumbnail.webp",{"live":114,"github":115},"https:\u002F\u002Flukaszdzielo.github.io\u002Fpokedex\u002F","https:\u002F\u002Fgithub.com\u002Flukaszdzielo\u002Fpokedex",{},true,"\u002Fog\u002Fprojects\u002Fpokedex-pl.jpg","\u002Fpl\u002Fprojekty\u002F2024\u002Fpokedex",{"title":5,"description":79},[122,123,124,35,125,126],"JavaScript (ES6+)","OOP","PokéAPI","SCSS","bez frameworków","pl\u002Fprojekty\u002F2024\u002Fpokedex\u002Findex",[129,130,131,132],"javascript","vanilla-js","oop","pokeapi","aQJXRVAYAjI8gpEXDegmJbNVlSIlxLlKc_55AN8Pat8",[135],{"id":136,"title":137,"art":138,"body":139,"date":287,"description":288,"draft":80,"extension":81,"image":6,"kind":289,"meta":290,"navigation":117,"ogImage":291,"path":292,"project":293,"seo":294,"slug":6,"stem":295,"tags":296,"translationKey":298,"updated":6,"__hash__":299},"blog_pl\u002Fpl\u002Fwpisy\u002F2024\u002Fpokedex-kilkadziesiat-zapytan-zamiast-tysiaca.md","Pokedex – kilkadziesiąt zapytań zamiast ponad tysiąca","\u002Fart\u002Fblog\u002Fpokedex.svg",{"type":8,"value":140,"toc":280},[141,144,147,151,154,157,169,179,183,200,203,210,214,217,231,234,238,241,252,256,270],[11,142,143],{},"Pokedex to mój pierwszy większy projekt w JavaScripcie. Pisałem go równolegle z kursem – bez frameworka, na własnych klasach. Chciałem zrobić coś trudniejszego niż kolejną listę zadań i coś, czego nie znalazłem gotowego.",[11,145,146],{},"Pokemony wybrałem z prostego powodu: są od lat, więc ktoś na pewno zbudował już dla nich API. Tak było – PokéAPI wyskoczyło w wyszukiwarce jako pierwsze. Dane wprowadza ktoś inny, a ja mogłem skupić się na kodzie.",[15,148,150],{"id":149},"problem-dane-są-w-wielu-miejscach","Problem: dane są w wielu miejscach",[11,152,153],{},"W PokéAPI każdy pokemon ma swój adres z kompletem danych. Najprostsza droga to jedno zapytanie na pokemona – tak robi większość tutoriali z pierwszą generacją. Przy ponad 1000 gatunków to ponad 1000 zapytań przy każdym wejściu na stronę. Bałem się, że to zbyt mocno obciąży serwer, a strona będzie się długo ładować.",[11,155,156],{},"Dlatego odwróciłem kolejność. Zamiast pytać każdego pokemona o jego typ, pytam każdy typ o jego pokemony:",[158,159,160,163,166],"ol",{},[23,161,162],{},"lista gatunków – jedno zapytanie daje numery i nazwy wszystkich pokemonów,",[23,164,165],{},"typy – każdy typ zwraca listę pokemonów, które go mają,",[23,167,168],{},"generacje – każda generacja zwraca listę swoich gatunków.",[11,170,171,172,174,175,178],{},"Zapytania o typy i generacje idą równolegle przez ",[27,173,29],{},". Do tego osobne zapytania o nazwy z myślnikiem – API zwraca np. ",[27,176,177],{},"mr-mime",", a na liście chciałem mieć „Mr. Mime”. W sumie wychodzi kilkadziesiąt zapytań zamiast ponad tysiąca.",[15,180,182],{"id":181},"mała-baza-w-przeglądarce","Mała baza w przeglądarce",[11,184,185,186,47,189,47,192,195,196,199],{},"Z tych odpowiedzi składam jeden obiekt: numer pokemona → nazwa, typy i generacja. Klucze są jednoliterowe (",[27,187,188],{},"n",[27,190,191],{},"t",[27,193,194],{},"g","), bo całość trafia do ",[27,197,198],{},"localStorage",", a tam miejsce jest ograniczone.",[11,201,202],{},"Przy kolejnej wizycie strona pyta API tylko o to, ile jest teraz gatunków. Jeśli liczba zgadza się z tą w pamięci, lista ładuje się z przeglądarki – to dwa zapytania zamiast kilkudziesięciu. Jeśli w API pojawią się nowe pokemony, baza zbuduje się od nowa sama. Tego chciałem od początku: żeby raz napisany kod działał dalej beze mnie.",[11,204,205,206,209],{},"Wzrost, waga i statystyki pobieram dopiero wtedy, gdy ktoś otworzy kartę pokemona. Trafiają do ",[27,207,208],{},"sessionStorage",", więc drugie otwarcie tej samej karty nie wysyła już zapytania.",[15,211,213],{"id":212},"co-chwilę-nowy-pomysł","Co chwilę nowy pomysł",[11,215,216],{},"Sama lista szybko mi nie wystarczyła. W trakcie pisania co chwilę chciałem coś dodać:",[20,218,219,222,225,228],{},[23,220,221],{},"zaznaczanie złapanych pokemonów – lista zapisuje się w przeglądarce,",[23,223,224],{},"import i eksport tej listy, żeby przenieść ją na inne urządzenie albo do innej przeglądarki,",[23,226,227],{},"jasny i ciemny motyw,",[23,229,230],{},"paginację z numerem strony w adresie, żeby link prowadził od razu w to samo miejsce.",[11,232,233],{},"Pomysłów było więcej niż czasu. Często zaczynałem kolejną rzecz, zanim poprzednia działała do końca tak, jak powinna – i potem wracałem do kilku miejsc naraz.",[15,235,237],{"id":236},"błędy-które-uczyły-najwięcej","Błędy, które uczyły najwięcej",[11,239,240],{},"Na początku kilka razy wpadłem w pętlę, która przeciążała komputer. Potem przyszła asynchroniczność – musiałem sprawdzać, gdzie wysyłam zapytanie, co dostaję i czy te dane w ogóle są mi potrzebne. Najtrudniejsze okazało się zgranie tego z DOM-em: dane już są, a widok jeszcze nie, albo odwrotnie.",[11,242,243,244,247,248,251],{},"Moim głównym narzędziem był ",[27,245,246],{},"console.log"," i ",[27,249,250],{},"console.trace",". Dziś częściej zatrzymałbym kod w debuggerze w miejscu, gdzie coś się dzieje – wtedy tego nie robiłem, a pewnie zaoszczędziłbym sporo czasu.",[15,253,255],{"id":254},"co-zrobiłbym-dziś-inaczej","Co zrobiłbym dziś inaczej",[20,257,258,261,264,267],{},[23,259,260],{},"Kończyłbym jedną funkcję, zanim zacznę następną. Do pracy małymi krokami doszedłem dopiero po jakimś czasie.",[23,262,263],{},"Najpierw przeanalizowałbym, jak API podaje dane i czego naprawdę potrzebuję, a dopiero potem pisał kod.",[23,265,266],{},"Może najpierw zrobiłbym wygląd, a potem funkcje – wygląd zmieniałem wiele razy w trakcie.",[23,268,269],{},"Nie wszystko musi być klasą. Niektóre części dziś napisałbym jako zwykłe funkcje.",[11,271,272,273,279],{},"Projekt nie wygląda na wielki, ale dla mnie był ważnym krokiem. Kiedyś chcę przepisać go na Vue – temat ten sam, nowa lekcja. Na razie ",[274,275,278],"a",{"href":114,"rel":276},[277],"nofollow","Pokedex działa tutaj",".",{"title":68,"searchDepth":69,"depth":69,"links":281},[282,283,284,285,286],{"id":149,"depth":69,"text":150},{"id":181,"depth":69,"text":182},{"id":212,"depth":69,"text":213},{"id":236,"depth":69,"text":237},{"id":254,"depth":69,"text":255},"2024-03-20","Jak w czystym JavaScripcie zbudowałem Pokedex na ponad 1000 pokemonów – z kolejnością pobierania danych z PokéAPI i małą bazą w przeglądarce.","post",{},"\u002Fog\u002Fblog\u002Fpokedex-pl.jpg","\u002Fpl\u002Fwpisy\u002F2024\u002Fpokedex-kilkadziesiat-zapytan-zamiast-tysiaca","\u002Fprojects\u002F2024\u002Fpokedex",{"title":137,"description":288},"pl\u002Fwpisy\u002F2024\u002Fpokedex-kilkadziesiat-zapytan-zamiast-tysiaca",[129,132,297],"projekt","pokedex-kilkadziesiat-zapytan-zamiast-tysiaca","j4ST6RX7Y1n__417v3iUezLoHp9O2aOHrJ04y5eNU4k",1792530551449]