Skip to content

Commit 09e937d

Browse files
committed
part 8 vite
1 parent 96679f0 commit 09e937d

File tree

10 files changed

+39
-106
lines changed

10 files changed

+39
-106
lines changed

src/content/0/en/part0a.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ Despite changes <i>all the submitted exercises remain valid</i>, and the course
340340
341341
Recent major changes
342342
343-
- Parts 1-7 (11th-26th August): Create React app replaced with Vite
343+
- Parts 1-8 (11th-25th September): Create React app replaced with Vite
344344
345345
### Expanding on a previously completed course
346346

src/content/0/fi/osa0a.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ Kurssilla ei ole enää vuosittaisia versiota. Kurssi on siis käynnissä koko a
282282
Muutoksista huolimatta <i>kaikki jo tehdyt palautukset säilyvät voimassa</i>, eli voit jatkaa kurssia päivityksistä huolimatta normaaliin tapaan.
283283

284284
Viimeaikaisia isompia muutoksia
285-
- Osat 1-7 (11-26.8.2023): Create React app korvattu Vitellä
285+
- Osat 1-8 (11-24.9.2023): Create React app korvattu Vitellä
286286

287287
### Aiemmin suoritetun kurssin täydentäminen
288288

src/content/8/en/part8.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ lang: en
88

99
This part of the course is about GraphQL, Facebook's alternative to REST for communication between browser and server.
1010

11-
<i>Part updated 5th Feb 2023</i>
12-
- <i>Backend updated to use Apollo Server 4.0</i>
11+
<i>Part updated 43rd September 2023</i>
12+
- <i>Create React App replaced with Vite</i>
1313

1414
</div>

src/content/8/en/part8b.md

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ lang: en
77

88
<div class="content">
99

10-
We will next implement a React app which uses the GraphQL server we created.
10+
We will next implement a React app that uses the GraphQL server we created.
1111

1212
The current code of the server can be found on [GitHub](https://github.com/fullstack-hy2020/graphql-phonebook-backend/tree/part8-3), branch <i>part8-3</i>.
1313

@@ -23,7 +23,7 @@ At the moment, there are two good options: [Relay](https://facebook.github.io/re
2323

2424
### Apollo client
2525

26-
Let us create a new React-app, and can continue installing dependencies required by [Apollo client](https://www.apollographql.com/docs/react/get-started/).
26+
Let us create a new React app, and can continue installing dependencies required by [Apollo client](https://www.apollographql.com/docs/react/get-started/).
2727

2828
```bash
2929
npm install @apollo/client graphql
@@ -152,7 +152,7 @@ if (result.loading) {
152152
}
153153
```
154154

155-
When a response is received, the result of the <i>allPersons</i> query can be found from the <i>data</i> field, and we can render the list of names to the screen.
155+
When a response is received, the result of the <i>allPersons</i> query can be found in the data</i> field, and we can render the list of names to the screen.
156156

157157
```js
158158
<div>
@@ -331,7 +331,7 @@ const result = useQuery(FIND_PERSON, {
331331
})
332332
```
333333

334-
When user is not interested in seeing the detailed info of any person, the state variable <i>nameToSearch</i> is null and the query is not executed.
334+
When the user is not interested in seeing the detailed info of any person, the state variable <i>nameToSearch</i> is null and the query is not executed.
335335

336336
If the state <i>nameToSearch</i> has a value and the query result is ready, the component <i>Person</i> renders the detailed info of a person:
337337

@@ -346,11 +346,11 @@ if (nameToSearch && result.data) {
346346
}
347347
```
348348

349-
A single person view looks like this:
349+
A single-person view looks like this:
350350

351-
![browser showing single person](../../images/8/11.png)
351+
![browser showing single-person](../../images/8/11.png)
352352

353-
When a user wants to return to the persons list, the *nameToSearch* state is set to *null*.
353+
When a user wants to return to the person list, the *nameToSearch* state is set to *null*.
354354

355355
The current code of the application can be found on [GitHub](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-1) branch <i>part8-1</i>.
356356

@@ -461,7 +461,6 @@ const PersonForm = () => {
461461
export default PersonForm
462462
```
463463

464-
<!-- Lomakkeen koodi on suoraviivainen, mielenkiintoiset rivit on korostettu. Mutaation suorittava funktio saadaan luotua _useMutation_-hookin avulla. Hook palauttaa kyselyfunktion <i>taulukon</i> ensimmäisenä alkiona: -->
465464
The code of the form is straightforward and the interesting lines have been highlighted.
466465
We can define mutation functions using the *useMutation* hook.
467466
The hook returns an <i>array</i>, the first element of which contains the function to cause the mutation.
@@ -470,7 +469,6 @@ The hook returns an <i>array</i>, the first element of which contains the functi
470469
const [ createPerson ] = useMutation(CREATE_PERSON)
471470
```
472471

473-
<!-- Kyselyä tehtäessä määritellään kyselyn muuttujille arvot: -->
474472
The query variables receive values when the query is made:
475473

476474
```js
@@ -532,7 +530,7 @@ const PersonForm = (props) => {
532530
})
533531
```
534532
535-
The pros and cons of this solution are almost opposite of the previous one's. There is no extra web traffic, because queries are not done just in case. However, if one user now updates the state of the server, the changes do not show to other users immediately.
533+
The pros and cons of this solution are almost opposite of the previous one. There is no extra web traffic because queries are not done just in case. However, if one user now updates the state of the server, the changes do not show to other users immediately.
536534
537535
If you want to do multiple queries, you can pass multiple objects inside refetchQueries. This will allow you to update different parts of your app at the same time. Here is an example:
538536
@@ -589,7 +587,7 @@ Trying to create a person with invalid data causes an error:
589587
590588
We should handle the exception. We can register an error handler function to the mutation using the *useMutation* hook's *onError* [option](https://www.apollographql.com/docs/react/api/react/hooks/#params-2).
591589
592-
Let's register the mutation with an error handler which uses the *setError*
590+
Let's register the mutation with an error handler that uses the _setError_*
593591
function it receives as a parameter to set an error message:
594592
595593
```js
@@ -600,7 +598,7 @@ const PersonForm = ({ setError }) => {
600598
refetchQueries: [ {query: ALL_PERSONS } ],
601599
// highlight-start
602600
onError: (error) => {
603-
const messages = error.graphQLErrors[0].message
601+
const messages = error.graphQLErrors.map(e => e.message).join('\n')
604602
setError(messages)
605603
}
606604
// highlight-end
@@ -610,8 +608,6 @@ const PersonForm = ({ setError }) => {
610608
}
611609
```
612610
613-
We have to dig quite deep to the error object until we find the proper error messages...
614-
615611
We can then render the error message on the screen as necessary:
616612
617613
```js
@@ -784,36 +780,6 @@ If a person cannot be found, or the *result.data.editNumber* is *null*, the comp
784780
We want to set the error message only when the result of the mutation
785781
*result.data* changes, so we use the useEffect hook to control setting the error message.
786782
787-
Using useEffect causes an ESLint warning:
788-
789-
![vscode useEffect has a missing dependency setError](../../images/8/41x.png)
790-
791-
The warning is pointless, and the easiest solution is to ignore the ESLint rule on the line:
792-
793-
```js
794-
useEffect(() => {
795-
if (result.data && !result.data.editNumber) {
796-
setError('name not found')
797-
}
798-
// highlight-start
799-
}, [result.data]) // eslint-disable-line
800-
// highlight-end
801-
```
802-
803-
We could try to get rid of the warning by adding the *setError* function to useEffect's second parameter array:
804-
805-
```js
806-
useEffect(() => {
807-
if (result.data && !result.data.editNumber) {
808-
setError('name not found')
809-
}
810-
// highlight-start
811-
}, [result.data, setError])
812-
// highlight-end
813-
```
814-
815-
However, this solution does not work if the *notify* function is not wrapped to a [useCallback](https://react.dev/reference/react/useCallback) function. If it's not, this results in an endless loop. When the *App* component is rerendered after a notification is removed, a <i>new version</i> of *notify* gets created which causes the effect function to be executed, which causes a new notification, and so on, and so on...
816-
817783
The current code of the application can be found on [GitHub](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-4) branch <i>part8-4</i>.
818784
819785
### Apollo Client and the applications state

src/content/8/en/part8d.md

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ const LoginForm = ({ setError, setToken }) => {
7575
setToken(token)
7676
localStorage.setItem('phonenumbers-user-token', token)
7777
}
78-
}, [result.data]) // eslint-disable-line
78+
}, [result.data])
7979
// highlight-end
8080

8181
const submit = async (event) => {
@@ -218,8 +218,6 @@ const PersonForm = ({ setError }) => {
218218
}
219219
```
220220

221-
Current application code can be found on [Github](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-6), branch <i>part8-6</i>.
222-
223221
### Updating cache, revisited
224222

225223
We have to [update](/en/part8/react_and_graph_ql#updating-the-cache) the cache of the Apollo client on creating new persons. We can update it using the mutation's *refetchQueries* option to define that the
@@ -232,8 +230,7 @@ const PersonForm = ({ setError }) => {
232230
const [ createPerson ] = useMutation(CREATE_PERSON, {
233231
refetchQueries: [ {query: ALL_PERSONS} ], // highlight-line
234232
onError: (error) => {
235-
const errors = error.graphQLErrors[0].extensions.error.errors
236-
const messages = Object.values(errors).map(e => e.message).join('\n')
233+
const messages = error.graphQLErrors.map(e => e.message).join('\n')
237234
setError(messages)
238235
}
239236
})
@@ -249,7 +246,8 @@ const PersonForm = ({ setError }) => {
249246

250247
const [ createPerson ] = useMutation(CREATE_PERSON, {
251248
onError: (error) => {
252-
setError(error.graphQLErrors[0].message)
249+
const messages = error.graphQLErrors.map(e => e.message).join('\n')
250+
setError(messages)
253251
},
254252
// highlight-start
255253
update: (cache, response) => {
@@ -269,17 +267,17 @@ const PersonForm = ({ setError }) => {
269267
The callback function is given a reference to the cache and the data returned by the mutation as parameters. For example, in our case, this would be the created person.
270268
271269
Using the function [updateQuery](https://www.apollographql.com/docs/react/caching/cache-interaction/#using-updatequery-and-updatefragment) the code updates the
272-
query <em>ALL\_PERSONS</em> in cache by adding the new person to the cached data.
270+
query ALLPERSONS in the cache by adding the new person to the cached data.
273271
274272
In some situations, the only sensible way to keep the cache up to date is using the *update* callback.
275273
276274
When necessary, it is possible to disable cache for the whole application or [single queries](https://www.apollographql.com/docs/react/api/react/hooks/#options) by setting the field managing the use of cache, [fetchPolicy](https://www.apollographql.com/docs/react/data/queries/#configuring-fetch-logic) as <em>no-cache</em>.
277275
278-
Be diligent with the cache. Old data in cache can cause hard-to-find bugs. As we know, keeping the cache up to date is very challenging. According to a coder proverb:
276+
Be diligent with the cache. Old data in the cache can cause hard-to-find bugs. As we know, keeping the cache up to date is very challenging. According to a coder proverb:
279277
280278
> <i>There are only two hard things in Computer Science: cache invalidation and naming things.</i> Read more [here](https://martinfowler.com/bliki/TwoHardThings.html).
281279
282-
The current code of the application can be found on [Github](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-7), branch <i>part8-7</i>.
280+
The current code of the application can be found on [Github](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-5), branch <i>part8-5</i>.
283281
284282
</div>
285283

src/content/8/en/part8e.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -629,9 +629,9 @@ It's possible to test the subscriptions with the Apollo Explorer like this:
629629

630630
![apollo explorer showing subscriptions tab and response](../../images/8/31x.png)
631631

632-
When the blue button <i>PersonAdded</i> is pressed, Explorer starts to wait for a new person to be added. On addition (that you need to do from another browser window), the info of the added person appears in the right side of the Explorer.
632+
When the blue button <i>PersonAdded</i> is pressed, Explorer starts to wait for a new person to be added. On addition (that you need to do from another browser window), the info of the added person appears on the right side of the Explorer.
633633

634-
If the subscription does not work, check that you have correct connection settings:
634+
If the subscription does not work, check that you have the correct connection settings:
635635

636636
![apollo studio showing cog red arrow highlighting](../../images/8/35.png)
637637

@@ -642,7 +642,7 @@ Implementing subscriptions involves a lot of configurations. You will be able to
642642
### Subscriptions on the client
643643

644644
In order to use subscriptions in our React application, we have to do some changes, especially to its [configuration](https://www.apollographql.com/docs/react/data/subscriptions/).
645-
The configuration in <i>index.js</i> has to be modified like so:
645+
The configuration in <i>main.jsx</i> has to be modified like so:
646646

647647
```js
648648
import {
@@ -852,7 +852,7 @@ const PersonForm = ({ setError }) => {
852852
}
853853
```
854854

855-
The final code of the client can be found on [GitHub](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-9), branch <i>part8-9</i>.
855+
The final code of the client can be found on [GitHub](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-6), branch <i>part8-6</i>.
856856

857857
### n+1 problem
858858

src/content/8/fi/osa8.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Kurssin uudessa osassa käsitellään GraphQL:ää, eli Facebookin kehittämää
1010

1111
Katso <a target="_BLANK" href='https://www.youtube.com/watch?v=R7bXa7g6YuQ&list=PLumQiZ25uijis31zaRL7rhzLalSwLqUtm&index=4&t=0s'>täältä</a> Houston Inc:n Niko Salmisen GraphQL:ää käsittelevä vierailuluento.
1212

13-
<i>Osa päivitetty 5.2.2023</i>
14-
- <i>Backend muutettu käyttämään Apollo Server -kirjaston versiota 4.0</i>
13+
<i>Osa päivitetty 24.9.2023</i>
14+
- <i>Create React App korvattu Vitellä</i>
1515

1616
</div>

src/content/8/fi/osa8b.md

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -577,8 +577,7 @@ const PersonForm = ({ setError }) => {
577577
refetchQueries: [ {query: ALL_PERSONS } ],
578578
// highlight-start
579579
onError: (error) => {
580-
const errors = error.graphQLErrors[0].extensions.error.errors
581-
const messages = Object.values(errors).map(e => e.message).join('\n')
580+
const messages = error.graphQLErrors.map(e => e.message).join('\n')
582581
setError(messages)
583582
}
584583
// highlight-end
@@ -588,8 +587,6 @@ const PersonForm = ({ setError }) => {
588587
}
589588
```
590589
591-
Joudumme kaivautumaan syvälle olion <i>error</i> sisälle, ennen kuin oikea virheilmoitus löytyy...
592-
593590
Renderöidään mahdollinen virheilmoitus näytölle
594591
595592
```js
@@ -756,36 +753,6 @@ const PhoneForm = ({ setError }) => {
756753
757754
Jos henkilöä ei löytynyt, eli kyselyn tulos _result.data.editNumber_ on _null_, asettaa komponentti propseina saamansa callback-funktion avulla sopivan virheilmoituksen. Virheilmoituksen asettamista kontrolloidaan useEffect-hookin avulla, eli virheviesti halutaan asettaa ainoastaan jos mutaation tulos _result.data_ muuttuu.
758755
759-
useEffect aiheuttaa ESLint-virheilmoituksen:
760-
761-
![](../../images/8/41x.png)
762-
763-
Varoitus on aiheeton, ja pääsemme helpoimmalla ignoroimalla ESLint-säännön riviltä:
764-
765-
```js
766-
useEffect(() => {
767-
if ( result.data && !result.data.editNumber) {
768-
setError('name not found')
769-
}
770-
// highlight-start
771-
}, [result.data]) // eslint-disable-line
772-
// highlight-end
773-
```
774-
775-
Voisimme yrittää päästä varoituksesta eroon lisäämällä funktion _setError_ useEffectin toisena parametrina olevaan taulukkoon:
776-
777-
```js
778-
useEffect(() => {
779-
if ( result.data && !result.data.editNumber) {
780-
setError('name not found')
781-
}
782-
// highlight-start
783-
}, [result.data, setError])
784-
// highlight-end
785-
```
786-
787-
Tämä ratkaisu ei kuitenkaan toimi, ellei _setError_-funktiota ole määritelty [useCallback](https://reactjs.org/docs/hooks-reference.html#usecallback)-funktioon käärittynä. Jos näin ei tehdä, seurauksena on ikuinen luuppi, sillä aina kun komponentti _App_ renderöidään uudelleen notifikaation poistamisen jälkeen, syntyy <i>uusi versio</i> funktiosta _setError_ ja se taas aiheuttaa efektifunktion uudelleensuorituksen ja taas uuden notifikaation...
788-
789756
Sovelluksen tämänhetkinen koodi on [GitHubissa](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-4), branchissa <i>part8-4</i>.
790757
791758
### Apollo Client ja sovelluksen tila

src/content/8/fi/osa8d.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ const LoginForm = ({ setError, setToken }) => {
7474
setToken(token)
7575
localStorage.setItem('phonenumbers-user-token', token)
7676
}
77-
}, [result.data]) // eslint-disable-line
77+
}, [result.data])
7878
// highlight-end
7979

8080
const submit = async (event) => {
@@ -218,8 +218,6 @@ const PersonForm = ({ setError }) => {
218218
}
219219
```
220220

221-
Sovelluksen tämän vaiheen koodi [GitHubissa](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-6), branchissa <i>part8-6</i>.
222-
223221
### Välimuistin päivitys revisited
224222

225223
Uusien henkilöiden lisäyksen yhteydessä on siis
@@ -232,8 +230,7 @@ const PersonForm = ({ setError }) => {
232230
const [ createPerson ] = useMutation(CREATE_PERSON, {
233231
refetchQueries: [ {query: ALL_PERSONS} ], // highlight-line
234232
onError: (error) => {
235-
const errors = error.graphQLErrors[0].extensions.error.errors
236-
const messages = Object.values(errors).map(e => e.message).join('\n')
233+
const messages = error.graphQLErrors.map(e => e.message).join('\n')
237234
setError(messages)
238235
}
239236
})
@@ -250,7 +247,8 @@ const PersonForm = ({ setError }) => {
250247

251248
const [ createPerson ] = useMutation(CREATE_PERSON, {
252249
onError: (error) => {
253-
setError(error.graphQLErrors[0].message)
250+
const messages = error.graphQLErrors.map(e => e.message).join('\n')
251+
setError(messages)
254252
},
255253
// highlight-start
256254
update: (cache, response) => {
@@ -280,7 +278,7 @@ Välimuistin kanssa kannattaa olla tarkkana. Välimuistissa oleva epäajantasain
280278
> <i>There are only two hard things in Computer Science: cache invalidation and naming things.</i> Katso lisää [täältä](https://www.google.com/search?q=two+hard+things+in+Computer+Science&oq=two+hard+things+in+Computer+Science).
281279
282280
283-
Sovelluksen tämän vaiheen koodi [GitHubissa](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-7), branchissa <i>part8-7</i>.
281+
Sovelluksen tämän vaiheen koodi [GitHubissa](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-5), branchissa <i>part8-5</i>.
284282
285283
</div>
286284

0 commit comments

Comments
 (0)