Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the solution code for “Using Async Storage” #810

Merged
merged 1 commit into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useEffect } from "react"
import { RestaurantsStackParamList } from "../../App"
import Loading from "../../components/Loading"
import RestaurantHeader from "../../components/RestaurantHeader"
import Box from "../../design/Box"
import Button from "../../design/Button"
import Screen from "../../design/Screen"
import Typography from "../../design/Typography"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useEffect } from "react"
import { RestaurantsStackParamList } from "../../App"
import Loading from "../../components/Loading"
import RestaurantHeader from "../../components/RestaurantHeader"
import Box from "../../design/Box"
import Button from "../../design/Button"
import Screen from "../../design/Screen"
import Typography from "../../design/Typography"
Expand All @@ -27,10 +28,12 @@ const RestaurantDetails: React.FC<RestaurantDetailsProps> = ({ route }) => {
if (error) {
return (
<Screen>
<Typography variant="heading">
Error loading restaurant details:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
<Box padding="m">
<Typography variant="heading">
Error loading restaurant details:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
</Box>
</Screen>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useEffect } from "react"
import { RestaurantsStackParamList } from "../../App"
import Loading from "../../components/Loading"
import RestaurantHeader from "../../components/RestaurantHeader"
import Box from "../../design/Box"
import Button from "../../design/Button"
import Screen from "../../design/Screen"
import Typography from "../../design/Typography"
Expand All @@ -27,10 +28,12 @@ const RestaurantDetails: React.FC<RestaurantDetailsProps> = ({ route }) => {
if (error) {
return (
<Screen>
<Typography variant="heading">
Error loading restaurant details:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
<Box padding="m">
<Typography variant="heading">
Error loading restaurant details:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
</Box>
</Screen>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ const RestaurantOrder: React.FC<RestaurantOrderProps> = ({ route }) => {
if (error) {
return (
<Screen>
<Typography variant="heading">
Error loading restaurant order:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
<Box padding="m">
<Typography variant="heading">
Error loading restaurant order:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
</Box>
</Screen>
)
}
Expand All @@ -55,7 +57,9 @@ const RestaurantOrder: React.FC<RestaurantOrderProps> = ({ route }) => {
if (!restaurant) {
return (
<Screen>
<Typography variant="heading">Restaurant not found</Typography>
<Box padding="m">
<Typography variant="heading">Restaurant not found</Typography>
</Box>
</Screen>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useEffect } from "react"
import { RestaurantsStackParamList } from "../../App"
import Loading from "../../components/Loading"
import RestaurantHeader from "../../components/RestaurantHeader"
import Box from "../../design/Box"
import Button from "../../design/Button"
import Screen from "../../design/Screen"
import Typography from "../../design/Typography"
Expand All @@ -27,10 +28,12 @@ const RestaurantDetails: React.FC<RestaurantDetailsProps> = ({ route }) => {
if (error) {
return (
<Screen>
<Typography variant="heading">
Error loading restaurant details:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
<Box padding="m">
<Typography variant="heading">
Error loading restaurant details:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
</Box>
</Screen>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,12 @@ const RestaurantOrder: React.FC<RestaurantOrderProps> = ({ route }) => {
if (error) {
return (
<Screen>
<Typography variant="heading">
Error loading restaurant order:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
<Box padding="m">
<Typography variant="heading">
Error loading restaurant order:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
</Box>
</Screen>
)
}
Expand All @@ -71,7 +73,9 @@ const RestaurantOrder: React.FC<RestaurantOrderProps> = ({ route }) => {
if (!restaurant) {
return (
<Screen>
<Typography variant="heading">Restaurant not found</Typography>
<Box padding="m">
<Typography variant="heading">Restaurant not found</Typography>
</Box>
</Screen>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ const RestaurantOrder: React.FC<RestaurantOrderProps> = ({ route }) => {
if (error) {
return (
<Screen>
<Typography variant="heading">
Error loading restaurant order:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
<Box padding="m">
<Typography variant="heading">
Error loading restaurant order:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
</Box>
</Screen>
)
}
Expand All @@ -73,7 +75,9 @@ const RestaurantOrder: React.FC<RestaurantOrderProps> = ({ route }) => {
if (!restaurant) {
return (
<Screen>
<Typography variant="heading">Restaurant not found</Typography>
<Box padding="m">
<Typography variant="heading">Restaurant not found</Typography>
</Box>
</Screen>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@ const RestaurantOrder: React.FC<RestaurantOrderProps> = ({ route }) => {
if (error) {
return (
<Screen>
<Typography variant="heading">
Error loading restaurant order:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
<Box padding="m">
<Typography variant="heading">
Error loading restaurant order:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
</Box>
</Screen>
)
}
Expand All @@ -75,7 +77,9 @@ const RestaurantOrder: React.FC<RestaurantOrderProps> = ({ route }) => {
if (!restaurant) {
return (
<Screen>
<Typography variant="heading">Restaurant not found</Typography>
<Box padding="m">
<Typography variant="heading">Restaurant not found</Typography>
</Box>
</Screen>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import AsyncStorage from "@react-native-async-storage/async-storage"

// Exercise: Implement the four `AsyncStorage` helpers in `storage.ts`.
// Exercise: Implement the four `AsyncStorage` helpers.
export const getData = async <T>(key: string): Promise<T | undefined> => {}

export const getAllKeys = (): Promise<readonly string[]> => {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export async function apiRequest<
if (method === "GET" && response.ok) {
await storeData<CachedResponse<Data>>(keyPrefix + requestUrl, {
data: data,
dateTime: new Date().toDateString(),
dateTime: new Date().toJSON(),
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useEffect } from "react"
import { RestaurantsStackParamList } from "../../App"
import Loading from "../../components/Loading"
import RestaurantHeader from "../../components/RestaurantHeader"
import Box from "../../design/Box"
import Button from "../../design/Button"
import Screen from "../../design/Screen"
import Typography from "../../design/Typography"
Expand Down Expand Up @@ -35,10 +36,12 @@ const RestaurantDetails: React.FC<RestaurantDetailsProps> = ({ route }) => {
if (error) {
return (
<Screen>
<Typography variant="heading">
Error loading restaurant details:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
<Box padding="m">
<Typography variant="heading">
Error loading restaurant details:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
</Box>
</Screen>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useEffect } from "react"
import { RestaurantsStackParamList } from "../../App"
import Loading from "../../components/Loading"
import RestaurantHeader from "../../components/RestaurantHeader"
import Box from "../../design/Box"
import Button from "../../design/Button"
import Screen from "../../design/Screen"
import Typography from "../../design/Typography"
Expand Down Expand Up @@ -37,10 +38,12 @@ const RestaurantDetails: React.FC<RestaurantDetailsProps> = ({ route }) => {
if (error) {
return (
<Screen>
<Typography variant="heading">
Error loading restaurant details:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
<Box padding="m">
<Typography variant="heading">
Error loading restaurant details:{" "}
</Typography>
<Typography variant="body">{error.message}</Typography>
</Box>
</Screen>
)
}
Expand Down
28 changes: 20 additions & 8 deletions src/react-native/15-using-asyncstorage/using-asyncstorage.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ This also means that classes and functions can't be serialized for storage.
Here is an example:

@sourceref ./async-setItem.ts
@highlight 6
@highlight 1, 5-6, only

This function takes a `restaurant` object, converts it into a string, and saves it under the key `"restaurantData"`.

Expand All @@ -58,7 +58,7 @@ The retrieved data, being in string format, often needs to be converted back int
Consider this example:

@sourceref ./async-getItem.ts
@highlight 5
@highlight 5-6, only

This function fetches the data stored under the `"restaurantData"` key and converts it from a string back into an object.

Expand Down Expand Up @@ -126,17 +126,24 @@ Here are some pointers on implementing this strategy:
npm install @react-native-async-storage/async-storage@1
```

✏️ Update **jest-setup.ts** to be:
✏️ Terminate the existing dev server and start it again:

@diff ../../../exercises/react-native/14-user-input/01-solution/jest-setup.ts ../../../exercises/react-native/15-async-storage/01-problem/jest-setup.ts only
```bash
npm run start
```

✏️ Create **src/services/storage/index.ts** and update it to be:
✏️ Update **jest-setup.ts** to be:

@sourceref ../../../exercises/react-native/15-async-storage/01-problem/src/services/storage/index.ts
@diff ../../../exercises/react-native/14-user-input/01-solution/jest-setup.ts ../../../exercises/react-native/15-async-storage/01-problem/jest-setup.ts only

✏️ Create **src/services/storage/storage.ts** and update it to be:

@sourceref ../../../exercises/react-native/15-async-storage/01-problem/src/services/storage/storage.ts
@highlight 3

✏️ Create **src/services/storage/index.ts** and update it to be:

@sourceref ../../../exercises/react-native/15-async-storage/01-problem/src/services/storage/index.ts

✏️ Update **src/services/pmo/api/api.ts** to be:

Expand Down Expand Up @@ -166,6 +173,10 @@ You can verify that this is working correctly by using DevTools to:
- View the requests (or lack thereof) being made.
- Inspect the stored data.

You can terminate the `api` server to check that uncached requests show an error.

**Hint:** Use [`new Date().toJSON()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON) to get the current datetime as a string.

### Solution 1

If you’ve implemented the solution correctly, the tests will pass when you run `npm run test`!
Expand All @@ -190,7 +201,7 @@ Our overall approach to caching the network responses seems great, although ther
Right now, we’re storing the datetime as a string in Async Storage, which means we have to parse it every time we check the cached response:

@sourceref ../../../exercises/react-native/15-async-storage/01-solution/src/services/pmo/api/api.ts
@highlight 7, 38-39, 69, only
@highlight 7, 38-39, 66, only

We could improve this by storing the datetime as a number instead, so we don’t have to parse it when fetching from the cache:

Expand Down Expand Up @@ -249,6 +260,7 @@ We’ll assume that the data is version `1` if we haven’t stored the version n
✏️ Create **src/services/DataMigration/DataMigration.tsx** and update it to be:

@sourceref ../../../exercises/react-native/15-async-storage/02-problem/src/services/DataMigration/DataMigration.tsx
@highlight 13, 21-23, only

✏️ Create **src/services/DataMigration/index.ts** and update it to be:

Expand Down Expand Up @@ -294,7 +306,7 @@ If you’ve implemented the solution correctly, the tests will pass when you run
<details>
<summary>Click to see the solution</summary>

✏️ Update **src/services/DataMigration/DataMigration.ts** to be:
✏️ Update **src/services/DataMigration/DataMigration.tsx** to be:

@diff ../../../exercises/react-native/15-async-storage/02-problem/src/services/DataMigration/DataMigration.tsx ../../../exercises/react-native/15-async-storage/02-solution/src/services/DataMigration/DataMigration.tsx only

Expand Down
Loading