Skip to content

Instantly share code, notes, and snippets.

@m5r
Created December 14, 2021 22:05
Show Gist options
  • Save m5r/1c53b693762aac9fcfdf9f15b144f5aa to your computer and use it in GitHub Desktop.
Save m5r/1c53b693762aac9fcfdf9f15b144f5aa to your computer and use it in GitHub Desktop.
Remix background jobs using a resource route
import type { ActionFunction } from "remix";
import { Form, redirect, useTransition } from "remix";
import { enqueueDeleteUserData } from "~/app/routes/queues/delete-user-data";
import authenticator from "~/app/auth/authenticator";
import { destroySession, getSession } from "~/utils/session.server";
import db from "~/utils/db.server";
export const action: ActionFunction = async ({ request }) => {
const user = await authenticator.isAuthenticated(request, { failureRedirect: "/auth/sign-in" });
await db.user.update({
where: { id: user.id },
data: { hashedPassword: "pending deletion" },
});
enqueueDeleteUserData({ userId: user.id });
return redirect("/", {
headers: {
"Set-Cookie": await destroySession(await getSession(request)),
},
});
};
export default function DeleteAccountForm() {
const isSubmitting = useTransition().state === "submitting";
return (
<Form method="post">
<button type="submit" disabled={isSubmitting}>
Delete my account
</button>
</Form>
);
}
import type { ActionFunction } from "remix";
import { enqueue } from "./enqueue";
import db from "~/utils/db.server";
type Payload = {
userId: string;
};
export const action: ActionFunction = async ({ request }) => {
const { userId } = await request.json();
await db.user.delete({ where: { id: userId } })
return null;
};
export function enqueueDeleteUserData(payload: Payload) {
enqueue({
route: "/queues/delete-user-data",
payload,
});
}
import type { ActionFunction } from "remix";
import serverConfig from "~/config/config.server";
export const action: ActionFunction = async ({ request }) => {
const { route, payload } = await request.json();
const req = new Request(`${serverConfig.app.baseUrl}${route}`, {
method: "POST",
body: JSON.stringify(payload),
headers: {
"Content-Type": "application/json",
},
credentials: "omit",
});
// don't await to return ASAP and handle the promise resolution without blocking
fetch(req)
.then(response => {
if (!response.ok) {
console.log("something wrong happened"); // TODO: implement retry mechanic
return;
}
})
.catch(error => console.error("error", error));
return null;
};
type EnqueueParams = {
route: string;
payload: unknown;
}
export function enqueue(params: EnqueueParams) {
const req = new Request(`${serverConfig.app.baseUrl}/queues/enqueue`, {
method: "POST",
body: JSON.stringify(params),
headers: {
"Content-Type": "application/json",
},
credentials: "omit",
});
fetch(req);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment