You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/0/fi/osa0a.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -39,7 +39,7 @@ Tämän kurssin eri osiin jo tehtyjen palautusten ajankäyttöstatistiikan näet
39
39
40
40
Kurssilla ei tällä hetkellä ole varsinaista opetusta, mutta tehtäviin voi yrittää kysyä apua kurssin keskustelukanavalla Discordissa <atarget='_blank'href='https://study.cs.helsinki.fi/discord/join/fullstack'>https://study.cs.helsinki.fi/discord/join/fullstack</a> sekä Telegramissa, kanavalla <atarget='_blank'href='https://t.me/fullstackcourse'>https://t.me/fullstackcourse</a>. Discordissa kurssiin liittyvää keskustelua varten on kanava fullstack_general ja osa-kohtaiset kanavat (muut fullstack-alkuiset kanavat). Huomaa, että Discordin <i>chat-kanava ei ole kurssiin liittyvää keskustelua varten</i>.
41
41
42
-
Huom: kaikki epäasialliset, halventavat ja jotain ihmisryhmää syrjivät kommentit kanavalla ovat kiellettyjä ja tälläisten kommenttien esittäjät poistetaan kanavalta.
42
+
Huom: kaikki epäasialliset, halventavat ja jotain ihmisryhmää syrjivät kommentit kanavalla ovat kiellettyjä ja tällaisten kommenttien esittäjät poistetaan kanavalta.
43
43
44
44
### Osat ja suorittaminen
45
45
@@ -284,7 +284,7 @@ Muutoksista huolimatta <i>kaikki jo tehdyt palautukset säilyvät voimassa</i>,
284
284
Viimeaikaisia isompia muutoksia
285
285
- Osa 2 (18.1.2023): Muutos tehtävien numeroinnissa, tehtävät 2.11-13. siirretty osan loppuun
286
286
- Osa 6 (30.1.2023): Uusi luku, aiheenaan React Query, useReducer ja React context korvasi Redux connect -luvun
287
-
- Osa 8 (5.2.2023): Backend muutettu käyttäämään Apollo Server -kirjaston versiota 4.0
287
+
- Osa 8 (5.2.2023): Backend muutettu käyttämään Apollo Server -kirjaston versiota 4.0
288
288
- Osa 9 (12.2.2023): Sisältöä tarkennettu, Patientor-esimerkkisovelluksen rakennetta yksinkertaistettu
Copy file name to clipboardExpand all lines: src/content/0/fi/osa0b.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,7 +15,7 @@ Kurssin suosittelemaa tyyliä noudattavan koodin kirjoittaminen alkaa [osasta 1]
15
15
16
16
Avataan selaimella [esimerkkisovellus](https://studies.cs.helsinki.fi/exampleapp/). Sivun ensimmäinen lataus kestää joskus hetken.
17
17
18
-
Kurssimateriaali olettaaa että käytössä Chrome-selain.
18
+
Kurssimateriaali olettaa että käytössä Chrome-selain.
19
19
20
20
**Web-sovelluskehityksen sääntö numero yksi**: pidä selaimen Developer-konsoli koko ajan auki. Konsoli avautuu Macilla painamalla yhtä aikaa _alt__cmd_ ja _i_. Windowsilla konsolin saa auki painamalla _F12_ tai yhtä aikaa _ctrl__shift_ ja _i_.
21
21
@@ -181,7 +181,7 @@ Osoitteesta löytyvät muistiinpanot [JSON](https://en.wikipedia.org/wiki/JSON)-
181
181
182
182

183
183
184
-
Ylläoleva muistiinpanojen sivun JavaScript-koodi siis lataa muistiinpanot sisältävän JSON-muotoisen datan ja muodostaa datan avulla selaimeen "bullet-listan" muistiinpanojen sisällöstä:
184
+
Yllä oleva muistiinpanojen sivun JavaScript-koodi siis lataa muistiinpanot sisältävän JSON-muotoisen datan ja muodostaa datan avulla selaimeen "bullet-listan" muistiinpanojen sisällöstä:
185
185
186
186
Tämän saa aikaan seuraava koodi:
187
187
@@ -306,7 +306,7 @@ Document Object Model eli [DOM](https://en.wikipedia.org/wiki/Document_Object_Mo
306
306
307
307
Edellisessä luvussa esittelemämme JavaScript-koodi käytti nimenomaan DOM-apia lisätäkseen sivulle muistiinpanojen listan.
308
308
309
-
Allaoleva koodi luo muuttujaan <em>ul</em> DOM-apin avulla uuden "solmun" ja lisää sille joukon lapsisolmuja:
309
+
Alla oleva koodi luo muuttujaan <em>ul</em> DOM-apin avulla uuden "solmun" ja lisää sille joukon lapsisolmuja:
310
310
311
311
```js
312
312
var ul =document.createElement('ul')
@@ -569,7 +569,7 @@ Sovelluksen koodi on osoitteessa <https://github.com/mluukkai/example_app>. Kann
569
569
570
570
Kurssin esimerkkisovellus on tehty ns. [Vanilla JavaScriptillä](https://medium.freecodecamp.org/is-vanilla-javascript-worth-learning-absolutely-c2c67140ac34) eli käyttäen pelkkää DOM-apia ja JavaScript-kieltä sivujen rakenteen manipulointiin.
571
571
572
-
Pelkän JavaScriptin ja DOM-apin käytön sijaan web-ohjelmoinnissa hyödynnetään yleensä kirjastoja, jotka sisältävät DOM-apia helpommin käytettäviä työkaluja sivujen muokkaamiseen. Eräs tälläinen kirjasto on edelleenkin hyvin suosittu [jQuery](https://jquery.com/).
572
+
Pelkän JavaScriptin ja DOM-apin käytön sijaan web-ohjelmoinnissa hyödynnetään yleensä kirjastoja, jotka sisältävät DOM-apia helpommin käytettäviä työkaluja sivujen muokkaamiseen. Eräs tällainen kirjasto on edelleenkin hyvin suosittu [jQuery](https://jquery.com/).
573
573
574
574
jQuery on kehitetty aikana, jolloin web-sivut olivat vielä suurimmaksi osaksi perinteisiä, eli palvelin muodosti HTML-sivuja, joiden toiminnallisuutta rikastettiin selaimessa jQueryllä kirjoitetun JavaScript-koodin avulla. Yksi syy jQueryn suosion taustalla oli niin sanottu cross-browser yhteensopivuus, eli kirjasto toimi selaimesta ja selainvalmistajasta riippumatta samalla tavalla, eikä sitä käyttäessä ollut enää tarvetta kirjoittaa selainversiokohtaisia ratkaisuja. Nykyisin tavallisen jQueryn käyttö ei ole enää yhtä perusteltua kuin aikaisemmin, JavaScript on kehittynyt paljon ja käytetyimmät selaimet tukevat yleisesti ottaen hyvin perustoiminnallisuuksia.
renderöi komponentin sisällön tiedoston <i>public/index.html</i> määrittelemään <i>div</i>-elementtiin, jonka <i>id:n</i> arvona on 'root'.
69
69
70
-
Tiedosto <i>public/index.html</i> on headerin määrittelyjä lukuunottamatta oleellisesti ottaen tyhjä:
70
+
Tiedosto <i>public/index.html</i> on headerin määrittelyjä lukuun ottamatta oleellisesti ottaen tyhjä:
71
71
72
72
```html
73
73
<!DOCTYPE html>
@@ -151,7 +151,7 @@ Web-sovelluskehityksen sääntö numero yksi on
151
151
152
152
> <i>pidä konsoli koko ajan auki</i>
153
153
154
-
Toistetaan tämä vielä yhdessä: <i>pidän konsolin koko ajan auki</i> tamän kurssin ja koko loppuelämäni ajan tehdessäni web-sovelluskehitystä.
154
+
Toistetaan tämä vielä yhdessä: <i>pidän konsolin koko ajan auki</i> tämän kurssin ja koko loppuelämäni ajan tehdessäni web-sovelluskehitystä.
155
155
156
156
Komponenttien sisällä on mahdollista renderöidä myös dynaamista sisältöä.
157
157
@@ -343,7 +343,7 @@ Komponentti <i>Hello</i> myös tulostaa props-olion arvon konsoliin.
343
343
344
344
Toivottavasti konsolisi on auki, jos ei ole, muista yhteinen lupauksemme:
345
345
346
-
> <i>pidän konsolin koko ajan auki tamän kurssin ja koko loppuelämäni ajan tehdessäni web-sovelluskehitystä</i>
346
+
> <i>pidän konsolin koko ajan auki tämän kurssin ja koko loppuelämäni ajan tehdessäni web-sovelluskehitystä</i>
347
347
348
348
Ohjemistokehitys on haastavaa, ja erityisen haastavaksi se muuttuu, jos jokainen mahdollinen apukeino kuten web-konsoli sekä komennolla _console.log_ tahtävät aputulostukset eivät ole käytössä. Ammattilaiset käyttävät näitä <i>aina</i>. Ei ole yhtään syytä miksi aloittelijan pitäisi jättää nämä fantastiset apuvälineet hyödyntämättä.
349
349
@@ -462,7 +462,7 @@ Mitään ei kuitenkaan tule ruudulle. Yritän etsiä koodista 15 minuutin ajan o
462
462
463
463
Vihdoin mieleeni palaa antamamme lupaus
464
464
465
-
> <i>pidän konsolin koko ajan auki tamän kurssin ja koko loppuelämäni ajan tehdessäni web-sovelluskehitystä</i>
465
+
> <i>pidän konsolin koko ajan auki tämän kurssin ja koko loppuelämäni ajan tehdessäni web-sovelluskehitystä</i>
466
466
467
467
Konsoli huutaakin punaisena:
468
468
@@ -560,7 +560,7 @@ Kunkin tehtäväsarjan ohjelmasta kannattaa palauttaa kaikki sovelluksen sisält
560
560
561
561
Tehtävät palautetaan **yksi osa kerrallaan**. Kun olet palauttanut osan tehtävät, et voi enää palauttaa saman osan tekemättä jättämiäsi tehtäviä.
562
562
563
-
Huomaa, että tässä osassa on muitakin tehtäviä kuin allaolevat. <i>Älä siis tee palautusta</i> ennen kun olet tehnyt osan tehtävistä kaikki, jotka haluat palauttaa.
563
+
Huomaa, että tässä osassa on muitakin tehtäviä kuin alla olevat. <i>Älä siis tee palautusta</i> ennen kun olet tehnyt osan tehtävistä kaikki, jotka haluat palauttaa.
564
564
565
565
**Vinkki:** Kun olet avaamassa tehtävääsi Visual Studio Codella, huomaathan avata koko projektin kansion editoriin. Tämä mahdollistaa editorissa helpomman tiedostojen välillä siirtymisen ja paremmat automaattiset täydennykset. Tämä onnistuu siirtymällä terminaalissa projektin kansioon ja komentamalla:
566
566
@@ -639,7 +639,7 @@ const App = () => {
639
639
640
640
**VAROITUS** älä yritä tehdä ohjelmassasi kaikkia komponentteja yhtä aikaa, sillä se johtaa lähes varmasti siihen että ohjelma ei toimi. Etene pieni askel kerrallaan, tee aluksi esim. komponentti <i>Header</i> ja vasta kun se toimii 100% varmasti, kannattaa edetä seuraavaan komponenttiin.
641
641
642
-
Huolellinen, pienin askelin eteneminen saattaa tuntua hitaalta, mutta se on itseasiassa <i> ylivoimaisesti nopein</i> tapa edetä. Kuuluisa ohjelmistokehittäjä Robert "Uncle Bob" Martin on todennut
642
+
Huolellinen, pienin askelin eteneminen saattaa tuntua hitaalta, mutta se on itse asiassa <i> ylivoimaisesti nopein</i> tapa edetä. Kuuluisa ohjelmistokehittäjä Robert "Uncle Bob" Martin on todennut
Copy file name to clipboardExpand all lines: src/content/13/fi/osa13c.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1245,7 +1245,7 @@ Nyt siis <i>User.findByPk</i>-kysely ei hae joukkueita, vaan ne haetaan tarvitta
1245
1245
1246
1246
#### Modelien ominaisuuksia
1247
1247
1248
-
On joitain tilanteita, missä emme oletusarvoisesti halua käsitellä kaikkia tietyn taulun rivejä. Eräs tälläinen tapaus voisi olla se, että emme normaalisti haluasi näyttää sovelluksessamme niitä käyttäjiä joiden tunnus on suljettu (<i>disabled</i>). Tälläisessä tilanteessa voisimme määritellä modelille oletusarvoisen [scopen](https://sequelize.org/master/manual/scopes.html):
1248
+
On joitain tilanteita, missä emme oletusarvoisesti halua käsitellä kaikkia tietyn taulun rivejä. Eräs tällainen tapaus voisi olla se, että emme normaalisti haluasi näyttää sovelluksessamme niitä käyttäjiä joiden tunnus on suljettu (<i>disabled</i>). Tälläisessä tilanteessa voisimme määritellä modelille oletusarvoisen [scopen](https://sequelize.org/master/manual/scopes.html):
Copy file name to clipboardExpand all lines: src/content/4/fi/osa4b.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -494,7 +494,7 @@ test('a valid note can be added ', async () => {
494
494
})
495
495
```
496
496
497
-
Testi ei itseasiassa mene läpi, sillä olemme vahingossa palauttaneet statuskoodin <i>200 OK</i> uuden muistiinpanon luomisen yhteydessä, parempi statuskoodi on <i>201 CREATED</i>. Muutetaan koodia siten että testi menee läpi:
497
+
Testi ei itse asiassa mene läpi, sillä olemme vahingossa palauttaneet statuskoodin <i>200 OK</i> uuden muistiinpanon luomisen yhteydessä, parempi statuskoodi on <i>201 CREATED</i>. Muutetaan koodia siten että testi menee läpi:
Copy file name to clipboardExpand all lines: src/content/5/fi/osa5d.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1056,7 +1056,7 @@ Testien ja frontendin koodin lopullinen versio on kokonaisuudessaan [GitHubissa]
1056
1056
1057
1057
### Tehtävät 5.17.-5.23.
1058
1058
1059
-
Tehdään osan lopuksi muutamia E2E-testejä blogisovellukseen. Ylläolevan materiaalin pitäisi riittää ainakin suurimmaksi osaksi tehtävien tekemiseen. Cypressin [dokumentaatiota](https://docs.cypress.io/guides/overview/why-cypress.html#In-a-nutshell) kannattaa ehdottomasti myös lueskella, kyseessä on ehkä paras dokumentaatio, mitä olen koskaan open source -projektissa nähnyt.
1059
+
Tehdään osan lopuksi muutamia E2E-testejä blogisovellukseen. Yllä olevan materiaalin pitäisi riittää ainakin suurimmaksi osaksi tehtävien tekemiseen. Cypressin [dokumentaatiota](https://docs.cypress.io/guides/overview/why-cypress.html#In-a-nutshell) kannattaa ehdottomasti myös lueskella, kyseessä on ehkä paras dokumentaatio, mitä olen koskaan open source -projektissa nähnyt.
1060
1060
1061
1061
Erityisesti kannattaa lukea luku [Introduction to Cypress](https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Cypress-Can-Be-Simple-Sometimes), joka toteaa
Copy file name to clipboardExpand all lines: src/content/6/fi/osa6a.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -254,7 +254,7 @@ Selitys on kokonaisuudessaan seuraava
254
254
255
255
Funktion <i>createStore</i> sijaan siis suositellaan käytettäväksi hieman "kehittyneempää" funktiota <i>configureStore</i>, ja mekin tulemme ottamaan sen käyttöömme kun olemme ottaneet Reduxin perustoiminnallisuuden haltuun.
256
256
257
-
Sivuhuomio: <i>createStore</i> on määritelty olevan "deprecated", joka yleensä tarkoittaa sitä, että ominaisuus tulee postumaan kirjaston jossain uudemmassa versiossa. Ylläoleva selitys ja [tämäkin](https://stackoverflow.com/questions/71944111/redux-createstore-is-deprecated-cannot-get-state-from-getstate-in-redux-ac) keskustelu paljastavat, että <i>createStore</i> ei tule poistumaan, ja sille onkin annettu ehkä hieman virheellisin perustein status <i>deprecated</i>. Funktio ei siis ole vanhentunut, mutta nykyään on olemassa suositeltavampi, uusi tapa tehdä suunilleen sama asia.
257
+
Sivuhuomio: <i>createStore</i> on määritelty olevan "deprecated", joka yleensä tarkoittaa sitä, että ominaisuus tulee postumaan kirjaston jossain uudemmassa versiossa. Yllä oleva selitys ja [tämäkin](https://stackoverflow.com/questions/71944111/redux-createstore-is-deprecated-cannot-get-state-from-getstate-in-redux-ac) keskustelu paljastavat, että <i>createStore</i> ei tule poistumaan, ja sille onkin annettu ehkä hieman virheellisin perustein status <i>deprecated</i>. Funktio ei siis ole vanhentunut, mutta nykyään on olemassa suositeltavampi, uusi tapa tehdä suunilleen sama asia.
258
258
259
259
### Redux-muistiinpanot
260
260
@@ -668,7 +668,7 @@ Varmista testeissä <i>deep-freeze</i>-kirjaston avulla, että kyseessä on <i>p
668
668
669
669
Aloita laajentamalla reduceria siten, että molemmat testeistä menevät läpi. Lisää tämän jälkeen loput testit ja niitä vastaava toiminnallisuus.
670
670
671
-
Reducerin toteutuksessa kannattaa ottaa mallia ylläolevasta [Redux-muistiinpanot](/osa6/flux_arkkitehtuuri_ja_redux#puhtaat-funktiot-immutable)-esimerkistä.
671
+
Reducerin toteutuksessa kannattaa ottaa mallia yllä olevasta [Redux-muistiinpanot](/osa6/flux_arkkitehtuuri_ja_redux#puhtaat-funktiot-immutable)-esimerkistä.
672
672
673
673
#### 6.2: Unicafe revisited, step2
674
674
@@ -739,7 +739,7 @@ const App = () => {
739
739
}
740
740
```
741
741
742
-
Molemmat toiminnallisuudet on toteutettu suoraviivaisesti. Huomionarvoista uuden muistiinpanon lisäämisessä on nyt se, että toisin kuin aiemmat Reactilla toteutetut lomakkeet, <i>emme ole</i> nyt sitoneet lomakkeen kentän arvoa komponentin <i>App</i> tilaan. React kutsuu tälläisiä lomakkeita [ei-kontrolloiduiksi](https://reactjs.org/docs/uncontrolled-components.html).
742
+
Molemmat toiminnallisuudet on toteutettu suoraviivaisesti. Huomionarvoista uuden muistiinpanon lisäämisessä on nyt se, että toisin kuin aiemmat Reactilla toteutetut lomakkeet, <i>emme ole</i> nyt sitoneet lomakkeen kentän arvoa komponentin <i>App</i> tilaan. React kutsuu tällaisia lomakkeita [ei-kontrolloiduiksi](https://reactjs.org/docs/uncontrolled-components.html).
743
743
744
744
> Ei-kontrolloiduilla lomakkeilla on tiettyjä rajoitteita. Ne eivät mahdollista esim. lennossa annettavia validointiviestejä, lomakkeen lähetysnapin disabloimista sisällön perusteella yms. Meidän käyttötapaukseemme ne kuitenkin tällä kertaa sopivat.
745
745
Voit halutessasi lukea aiheesta enemmän [täältä](https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/).
Copy file name to clipboardExpand all lines: src/content/6/fi/osa6d.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -800,7 +800,7 @@ Yksinkertaisessa sovelluksessa <i>useState</i> on varmasti hyvä lähtökohta. J
800
800
801
801
Kaikkien kattavimman ja järeimmän tilanhallintaratkaisun tarjoaa Redux, joka on eräs tapa toteuttaa ns. [Flux](https://facebook.github.io/flux/)-arkkitehtuuri. Redux on hieman vanhempi kuin tässä aliosassa esitetyt ratkaisut. Reduxin jähmeys onkin ollut motivaationa monille uusille tilanhallintaratkaisuille kuten tässä osassa esittelemällemme Reactin <i>useReducer</i>:ille. Osa Reduxin jäykkyyteen kohdistuvasta kritiikistä tosin on jo vanhentunut [Redux Toolkit](https://redux-toolkit.js.org/):in ansiosta.
802
802
803
-
Vuosien saatossa on myös kehitelty muita Reduxia vastaavia tilantahallintakirjastoja, kuten esim. uudempi tulokas [Recoil](https://recoiljs.org/) ja hieman iäkkäämpi [MobX](https://mobx.js.org/). [Npm trendsien](https://npmtrends.com/mobx-vs-recoil-vs-redux) perusteella Redux kuitenkin dominoi edelleen selvästi, ja näyttää itseasiassa vaan kasvattavan etumatkaansa:
803
+
Vuosien saatossa on myös kehitelty muita Reduxia vastaavia tilantahallintakirjastoja, kuten esim. uudempi tulokas [Recoil](https://recoiljs.org/) ja hieman iäkkäämpi [MobX](https://mobx.js.org/). [Npm trendsien](https://npmtrends.com/mobx-vs-recoil-vs-redux) perusteella Redux kuitenkin dominoi edelleen selvästi, ja näyttää itse asiassa vaan kasvattavan etumatkaansa:
Copy file name to clipboardExpand all lines: src/content/7/fi/osa7b.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -232,7 +232,7 @@ const App = () => {
232
232
233
233
### Spread-attribuutit
234
234
235
-
Pääsemme itseasiassa helpommalla. Koska oliolla _name_ on nyt täsmälleen ne kentät, jotka <i>input</i>-komponentti odottaa saavansa propseina, voimme välittää propsit hyödyntäen [spread-syntaksia](https://reactjs.org/docs/jsx-in-depth.html#spread-attributes) seuraavasti:
235
+
Pääsemme itse asiassa helpommalla. Koska oliolla _name_ on nyt täsmälleen ne kentät, jotka <i>input</i>-komponentti odottaa saavansa propseina, voimme välittää propsit hyödyntäen [spread-syntaksia](https://reactjs.org/docs/jsx-in-depth.html#spread-attributes) seuraavasti:
Huomaamme, että koodi ei itse asiassa välitä ollenkaan siitä, että se käsittelee nimenomaan muistiinpanoja. Muuttujan _baseUrl_ arvoa lukuunottamatta käytännössä sama koodi voi hoitaa myös blogisovelluksen frontendin ja backendin välistä kommunikointia.
451
+
Huomaamme, että koodi ei itse asiassa välitä ollenkaan siitä, että se käsittelee nimenomaan muistiinpanoja. Muuttujan _baseUrl_ arvoa lukuun ottamatta käytännössä sama koodi voi hoitaa myös blogisovelluksen frontendin ja backendin välistä kommunikointia.
452
452
453
453
Eristä kommunikoiva koodi hookiksi _useResource_. Riittää, että kaikkien olioiden haku ja uuden olion luominen onnistuvat.
0 commit comments