This repository has been archived by the owner on Mar 5, 2023. It is now read-only.
This repository has been archived by the owner on Mar 5, 2023. It is now read-only.
createMachine
calls can only appear in the variable declaration or as a default export #77
Open
Description
Following the Reddit tutorial, there's a section that demonstrates splitting machines. In that section, they create a factory that creates a machine given a subreddit name. This is my translation to typescript
import { assign, createMachine } from "@xstate/compiled";
type SubredditContext = {
subreddit: string;
posts?: unknown[];
lastUpdated?: Date;
error?: string;
};
export type SubredditEvent = { type: "REFRESH" } | { type: "RETRY" };
export const createSubredditMachine = (subreddit: string) => {
return createMachine<SubredditContext, SubredditEvent, "subreddit">({
id: "subreddit",
initial: "loading",
context: {
subreddit,
posts: undefined,
lastUpdated: undefined,
error: undefined,
},
states: {
loading: {
invoke: {
id: "fetch-subreddit",
src: invokeFetchSubreddit,
onDone: {
target: "loaded",
actions: assign({
posts: (_, event) => event.data,
lastUpdated: (_) => new Date(),
}),
},
onError: "failure",
},
},
loaded: {
on: {
REFRESH: "loading",
},
},
failure: {
on: {
RETRY: "loading",
},
},
},
});
};
function invokeFetchSubreddit(context: SubredditContext) {
const { subreddit } = context;
return fetch(`https://www.reddit.com/r/${subreddit}.json`)
.then((res) => res.json())
.then((json) => json.data.children.map((child: any) => child.data));
}
As you may guess, xstate-codegen
has an issue with it since we're not exporting the machine. The only thing that I can come up with is:
- extract the
createMachine
outside of the function and export it. - set
context.subreddit
as optional. - Change
createSubredditMachine
to:
export const createSubredditMachine = (subreddit: string) => {
subredditMachine.withContext({ subreddit });
};
The only thing that bugs me is that I had to set the subreddit
as optional. Is there a better way of handling this?
Metadata
Assignees
Labels
No labels