Skip to content

Commit 0718571

Browse files
Add json fetch support
1 parent 1721161 commit 0718571

3 files changed

Lines changed: 77 additions & 6 deletions

File tree

‎app/model/fetching.ts‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
export const identifiers = {
2+
getJSON: "getJSON",
3+
} as const;
4+
5+
export function getJSON(url: string | URL) {
6+
return Object.freeze({
7+
type: identifiers.getJSON,
8+
url: url.toString(),
9+
});
10+
}
11+
12+
export type FetchMessage = ReturnType<typeof getJSON>;
13+
export type FetchReply = any;
14+
15+
export type FetchGenerator<Result> = Generator<
16+
FetchMessage,
17+
Result,
18+
FetchReply | undefined
19+
>;
20+
21+
export async function fetchController<Result>(
22+
baseURL: URL,
23+
generator: () => FetchGenerator<Result>
24+
) {
25+
const gen = generator();
26+
let reply: FetchReply | undefined;
27+
28+
while (true) {
29+
const result = gen.next(reply);
30+
if (result.done) {
31+
return result.value;
32+
}
33+
34+
reply = undefined;
35+
36+
if (result.value.type === identifiers.getJSON) {
37+
const url = new URL(result.value.url, baseURL);
38+
const data = fetch(url.toString()).then(res => res.json());
39+
reply = await data;
40+
}
41+
}
42+
}

‎app/model/schemas.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export type SchemaGenerator<Result> = Generator<
2323
SchemaReply | any
2424
>;
2525

26-
export function parseSchema<Result>(
26+
export function parseJSON<Result>(
2727
source: Record<string, any>,
2828
generator: () => SchemaGenerator<Result>
2929
) {

‎app/routes/make/schema.tsx‎

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { useState } from "react";
66
import { useEffect } from "react";
77
import {
88
parseFormData,
9-
parseSchema,
9+
parseJSON,
1010
read,
1111
SchemaGenerator,
1212
} from "../../model/schemas";
@@ -30,7 +30,6 @@ function useFetch<Data>(source: URL): null | Data {
3030
const [data, setData] = useState<Data | null>(null);
3131

3232
useEffect(() => {
33-
console.log("Fetching");
3433
const controller = new AbortController();
3534
const signal = controller.signal;
3635

@@ -77,9 +76,37 @@ function* ProfileSchema(): SchemaGenerator<ProfileData> {
7776
};
7877
}
7978

79+
interface SwapiPersonData {
80+
name: string;
81+
height: string;
82+
mass: string;
83+
}
84+
function* SwapiPersonSchema(): SchemaGenerator<SwapiPersonData> {
85+
const name: string = yield read.string("name");
86+
const height: string = yield read.string("height");
87+
const mass: string = yield read.string("mass");
88+
89+
return {
90+
name,
91+
height,
92+
mass,
93+
};
94+
}
95+
function* SwapiPersonResource(): SchemaGenerator<SwapiPersonData> {
96+
const name: string = yield read.string("name");
97+
const height: string = yield read.string("height");
98+
const mass: string = yield read.string("mass");
99+
100+
return {
101+
name,
102+
height,
103+
mass,
104+
};
105+
}
106+
80107
export default function MakeRenderer() {
81108
function renderExample(input: any): JSX.Element {
82-
const result = parseSchema(input, AWSRegionSchema);
109+
const result = parseJSON(input, AWSRegionSchema);
83110

84111
return (
85112
<div {...X(2)}>
@@ -97,14 +124,16 @@ export default function MakeRenderer() {
97124
favoriteNumber: 7,
98125
});
99126

100-
const personData = useFetch(new URL(`https://swapi.py4e.com/api/people/1`));
127+
const personDataRaw: any = useFetch(new URL(`https://swapi.py4e.com/api/people/1`));
128+
const personData = personDataRaw != null ? parseJSON(personDataRaw, SwapiPersonSchema) : null;
129+
// const personData = personDataRaw;
101130

102131
return (
103132
<main data-measure="center">
104133
<h1>Schema</h1>
105134

106135
<h2>JSON</h2>
107-
<CodeBlock language="javascript">{parseSchema.toString()}</CodeBlock>
136+
<CodeBlock language="javascript">{parseJSON.toString()}</CodeBlock>
108137

109138
<h2>Form Data</h2>
110139
<CodeBlock language="javascript">{parseFormData.toString()}</CodeBlock>

0 commit comments

Comments
 (0)