Skip to content

Commit 7e6527d

Browse files
committed
update the example app to use the new async status typing
1 parent dfcee8f commit 7e6527d

File tree

3 files changed

+137
-70
lines changed

3 files changed

+137
-70
lines changed

example/src/AsyncRendererExample.tsx

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,77 @@
11
// Copyright 2022 MFB Technologies, Inc.
22

3-
import { AsyncRequestStatus, createAsyncRenderer } from "@mfbtech/react-async-renderer"
3+
import {
4+
AsyncRequestStatus,
5+
AsyncRequestStatusEnum,
6+
createAsyncRenderer
7+
} from "@mfbtech/react-async-renderer"
48
import { useState } from "react"
59
import "./AsyncRendererExample.css"
610

711
export function AsyncRendererExample() {
8-
const [currentAsyncRequestState, setCurrentAsyncRequestState] = useState(AsyncRequestStatus.INIT)
9-
const asyncRequestError = currentAsyncRequestState === AsyncRequestStatus.ERROR ? "some error occurred!" : null
10-
const asyncRequestData = currentAsyncRequestState === AsyncRequestStatus.FULFILLED ? { data: "my data" } : null
12+
const [currentAsyncRequestState, setCurrentAsyncRequestState] =
13+
useState<AsyncRequestStatus>(AsyncRequestStatusEnum.INIT)
14+
const asyncRequestError =
15+
currentAsyncRequestState === AsyncRequestStatusEnum.ERROR
16+
? "some error occurred!"
17+
: null
18+
const asyncRequestData =
19+
currentAsyncRequestState === AsyncRequestStatusEnum.FULFILLED
20+
? { data: "my data" }
21+
: null
1122
const renderer = createAsyncRenderer({
1223
status: currentAsyncRequestState,
1324
error: asyncRequestError,
14-
onCompletedSuccessfullyArgs: asyncRequestData,
25+
onCompletedSuccessfullyArgs: asyncRequestData
1526
})
1627

1728
return (
1829
<div className="async-renderer-example">
1930
<h2>Async renderer example</h2>
2031
<div>
21-
<label htmlFor="asyncRequestStatus">Status of the long running process:</label>
32+
<label htmlFor="asyncRequestStatus">
33+
Status of the long running process:
34+
</label>
2235
<select
2336
value={currentAsyncRequestState}
24-
onChange={(e) => {
25-
setCurrentAsyncRequestState(e.currentTarget.value as AsyncRequestStatus)
37+
onChange={e => {
38+
setCurrentAsyncRequestState(
39+
e.currentTarget.value as AsyncRequestStatus
40+
)
2641
}}
27-
id="asyncRequestStatus">
28-
{
29-
Object.entries(AsyncRequestStatus).map(([name, value]) => {
30-
return (
31-
<option key={value} value={value}>{name}</option>
32-
)
33-
})
34-
}
42+
id="asyncRequestStatus"
43+
>
44+
{Object.entries(AsyncRequestStatusEnum).map(([name, value]) => {
45+
return (
46+
<option key={value} value={value}>
47+
{name}
48+
</option>
49+
)
50+
})}
3551
</select>
3652
</div>
3753
<div>
38-
{renderer((args) => {
39-
return (
40-
<p className='renderer-result success'>{args.data}</p>
41-
)
42-
},
54+
{renderer(
55+
args => {
56+
return <p className="renderer-result success">{args.data}</p>
57+
},
4358
{
44-
onInit: () => (<p className='renderer-result info'>Waiting for long running process to start...</p>),
45-
onLoading: () => (<p className='renderer-result loading'>custom spinner...</p>),
46-
onCompletedWithError: (props) => (<p className='renderer-result error'>{props.errorMessage ?? "error"}</p>)
47-
})}
59+
onInit: () => (
60+
<p className="renderer-result info">
61+
Waiting for long running process to start...
62+
</p>
63+
),
64+
onLoading: () => (
65+
<p className="renderer-result loading">custom spinner...</p>
66+
),
67+
onCompletedWithError: props => (
68+
<p className="renderer-result error">
69+
{props.errorMessage ?? "error"}
70+
</p>
71+
)
72+
}
73+
)}
4874
</div>
4975
</div>
5076
)
51-
}
77+
}

example/src/CascadedAsyncStateExample.tsx

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,33 @@
11
// Copyright 2022 MFB Technologies, Inc.
22

3-
import { AsyncRequestStatus, createAsyncRenderer, getCascadedAsyncState } from "@mfbtech/react-async-renderer"
3+
import {
4+
AsyncRequestStatus,
5+
AsyncRequestStatusEnum,
6+
createAsyncRenderer,
7+
getCascadedAsyncState
8+
} from "@mfbtech/react-async-renderer"
49
import { useState } from "react"
510
import "./CascadedAsyncStateExample.css"
611
import { useLongRunningProcess } from "./useLongRunningProcess"
712

813
export function CascadedAsyncStateExample() {
914
const [startProcesses, setStartProcesses] = useState(false)
10-
const processThree = useLongRunningProcess(1000, "process 3 data", startProcesses === false)
11-
const processOne = useLongRunningProcess(3000, "process 1 data", startProcesses === false)
15+
const processThree = useLongRunningProcess(
16+
1000,
17+
"process 3 data",
18+
startProcesses === false
19+
)
20+
const processOne = useLongRunningProcess(
21+
3000,
22+
"process 1 data",
23+
startProcesses === false
24+
)
1225
const processTwo = useLongRunningProcess(
1326
3000,
1427
"process 2 data",
1528
// Delay process 2 until process 3 has finished
16-
startProcesses === false || processThree.status !== AsyncRequestStatus.FULFILLED
29+
startProcesses === false ||
30+
processThree.status !== AsyncRequestStatusEnum.FULFILLED
1731
)
1832

1933
const cascadedStatus = getCascadedAsyncState([
@@ -41,10 +55,11 @@ export function CascadedAsyncStateExample() {
4155
<div className="cascaded-async-state-example">
4256
<h2>Cascaded async state example</h2>
4357
<p>
44-
Process 3 depends on process 2, which depends on process 1. Process 3 is hard coded to
45-
finish first, then process 1 and finally process 2. The success state will not be rendered
46-
until process 3 and its dependencies have finished. If any of the processes fail then the
47-
error state will be rendered.
58+
Process 3 depends on process 2, which depends on process 1. Process 3 is
59+
hard coded to finish first, then process 1 and finally process 2. The
60+
success state will not be rendered until process 3 and its dependencies
61+
have finished. If any of the processes fail then the error state will be
62+
rendered.
4863
</p>
4964
<div>
5065
<button onClick={resetProcesses}>Reset</button>
@@ -54,11 +69,23 @@ export function CascadedAsyncStateExample() {
5469
</div>
5570
<div>
5671
{renderer(
57-
data => (<>{
58-
Object.entries(data).map(([key, value]) => (<p key={key}>{value}</p>))
59-
}</>),
72+
data => (
73+
<>
74+
{Object.entries(data).map(([key, value]) => (
75+
<p key={key}>{value}</p>
76+
))}
77+
</>
78+
),
6079
{
61-
onInit: () => (<button onClick={() => { setStartProcesses(true) }}>Start</button>),
80+
onInit: () => (
81+
<button
82+
onClick={() => {
83+
setStartProcesses(true)
84+
}}
85+
>
86+
Start
87+
</button>
88+
)
6289
}
6390
)}
6491
</div>
@@ -68,20 +95,20 @@ export function CascadedAsyncStateExample() {
6895

6996
function getAsyncStatusUi(status: AsyncRequestStatus) {
7097
switch (status) {
71-
case AsyncRequestStatus.INIT: {
98+
case AsyncRequestStatusEnum.INIT: {
7299
return "🔵 - init"
73100
}
74-
case AsyncRequestStatus.PENDING: {
101+
case AsyncRequestStatusEnum.PENDING: {
75102
return "🟡 - pending"
76103
}
77-
case AsyncRequestStatus.FULFILLED: {
104+
case AsyncRequestStatusEnum.FULFILLED: {
78105
return "🟢 - fulfilled"
79106
}
80-
case AsyncRequestStatus.ERROR: {
107+
case AsyncRequestStatusEnum.ERROR: {
81108
return "🔴 - error"
82109
}
83110
default: {
84111
return "wasn't expecting that status... 🤷‍♂️"
85112
}
86113
}
87-
}
114+
}

example/src/useLongRunningProcess.ts

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
// Copyright 2022 MFB Technologies, Inc.
22

3-
import { AsyncRequestStatus } from "@mfbtech/react-async-renderer"
3+
import {
4+
AsyncRequestStatus,
5+
AsyncRequestStatusEnum
6+
} from "@mfbtech/react-async-renderer"
47
import { useEffect, useState } from "react"
58

69
/** starts a process that takes the specified amount of time and returns the specified data. */
7-
export function useLongRunningProcess<T>(processDurationInSeconds: number, processData: T, skip: boolean) {
8-
const [status, setStatus] = useState<AsyncRequestStatus>(AsyncRequestStatus.INIT)
10+
export function useLongRunningProcess<T>(
11+
processDurationInSeconds: number,
12+
processData: T,
13+
skip: boolean
14+
) {
15+
const [status, setStatus] = useState<AsyncRequestStatus>(
16+
AsyncRequestStatusEnum.INIT
17+
)
918
const [error, setError] = useState<null | string>(null)
1019
const [data, setData] = useState<null | T>(null)
1120
const [restart, setRestart] = useState(true)
@@ -17,44 +26,49 @@ export function useLongRunningProcess<T>(processDurationInSeconds: number, proce
1726
if (skip) {
1827
return
1928
}
20-
setStatus(AsyncRequestStatus.PENDING)
21-
startLongRunningProcess(processDurationInSeconds, processData).then(data => {
22-
setError(null)
23-
setStatus(AsyncRequestStatus.FULFILLED)
24-
setData(data)
25-
}).catch((err: unknown) => {
26-
setData(null)
27-
setStatus(AsyncRequestStatus.ERROR)
28-
let errorMessage = "error"
29-
if (typeof err === "string") {
30-
errorMessage = err
31-
}
32-
else if (err instanceof Error) {
33-
errorMessage = err.message
34-
}
35-
setError(errorMessage)
36-
}).finally(() => {
37-
setRestart(false)
38-
})
29+
setStatus(AsyncRequestStatusEnum.PENDING)
30+
startLongRunningProcess(processDurationInSeconds, processData)
31+
.then(data => {
32+
setError(null)
33+
setStatus(AsyncRequestStatusEnum.FULFILLED)
34+
setData(data)
35+
})
36+
.catch((err: unknown) => {
37+
setData(null)
38+
setStatus(AsyncRequestStatusEnum.ERROR)
39+
let errorMessage = "error"
40+
if (typeof err === "string") {
41+
errorMessage = err
42+
} else if (err instanceof Error) {
43+
errorMessage = err.message
44+
}
45+
setError(errorMessage)
46+
})
47+
.finally(() => {
48+
setRestart(false)
49+
})
3950
}, [processData, processDurationInSeconds, restart, skip])
4051

4152
return {
4253
status,
4354
error,
4455
data,
4556
reset: () => {
46-
setStatus(AsyncRequestStatus.INIT)
57+
setStatus(AsyncRequestStatusEnum.INIT)
4758
setError(null)
4859
setData(null)
4960
setRestart(true)
5061
}
5162
}
5263
}
5364

54-
function startLongRunningProcess<T>(processDurationInSeconds: number, processData: T): Promise<T> {
55-
return new Promise((resolve) => {
65+
function startLongRunningProcess<T>(
66+
processDurationInSeconds: number,
67+
processData: T
68+
): Promise<T> {
69+
return new Promise(resolve => {
5670
setTimeout(() => {
5771
resolve(processData)
58-
}, processDurationInSeconds);
72+
}, processDurationInSeconds)
5973
})
60-
}
74+
}

0 commit comments

Comments
 (0)