You should create a “status”, which you can then update throughout the Job if you’d like to. You can create more than one status. Each of these will come through to the hook with the latest status and the history for each.
jobs/yourjob.ts
//your jobclient.defineJob({ id: "meme-generator", name: "Generate memes", version: "0.1.1", trigger: eventTrigger({ name: "generate-memes", }), run: async (payload, io, ctx) => { //create a status "generating-memes" //you give it the starting state. Only label is required const generatingMemes = await io.createStatus("generating-memes", { //the label is compulsory on this first call label: "Generating memes", //state is optional state: "loading", //data is an optional object. the values can be any type that is JSON serializable data: { progress: 0.1, }, }); //...do stuff, like generate memes //update the generatingMemes status. //anything set here will override the previous values, but you'll be able to view the full history with hooks await generatingMemes.update("middle-generation", { //label isn't specified so will remain the same //state will be updated to "success" state: "success", //set data, this overrides the previous value data: { progress: 1, urls: [ "https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExZnZoMndsdWh0MmhvY2kyaDF6YjZjZzg1ZGsxdnhhYm13a3Q1Y3lkbyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/13HgwGsXF0aiGY/giphy.gif", ], }, }); },});
In this case we created just a single status generating-memes and then updated it. It’s worth noting that you can create as many statuses as you’d like in a single Job and you can update them as many times as you want.
This allows you to fine-grained control over how you report progress and output data from your Job.
The useEventRunStatuses hook will give you the statuses and overview data of the first run that is triggered by an event.
When you use
sendEvent it will
return basic details about the event, including the id of the event. You can
then pass this to your frontend to use in the useEventRunDetails hook.
This component will show the details of a Run and the status of each task in the Run:
import { useEventRunStatuses } from "@trigger.dev/react";export function EventRunData({ id }: { id: string }) { const { fetchStatus, error, statuses, run } = useEventRunStatuses(id); if (fetchStatus === "loading") { return <p>Loading...</p>; } if (fetchStatus === "error") { return ( <div> <p>{error.name}</p> <p>{error.message}</p> </div> ); } return ( <> //you receive the overall status of the run, e.g. SUCCESS, FAIL <div>Run status: {run.status}</div> <div> {statuses.map((status) => { switch (status.key) { case "generating-memes": { const urls = status.data?.urls as string[] | undefined; return ( <div key={status.key}> // Will display: "Generating memes: loading" <p> {status.label}: {status.state} </p> //will render the memes as images {urls?.map((url) => <img key={url} src={url} />)} </div> ); } } })} </div> //this is what's returned from the run function {run.output && ( <code> <pre>{JSON.stringify(run.output, null, 2)}</pre> </code> )} </> );}
The useRunStatuses hook will give you the statuses and overview data of a specific Run.
You can call client.getRuns() with a Job id to get a
list of the most recent Runs for that Job. You can then pass that run id to your frontend to use
in the hook.
This component will show the details of a Run and the status of each task in the Run:
import { useRunStatuses } from "@trigger.dev/react";export function RunData({ id }: { id: string }) { const { fetchStatus, error, statuses, run } = useRunStatuses(id); if (fetchStatus === "loading") { return <p>Loading...</p>; } if (fetchStatus === "error") { return ( <div> <p>{error.name}</p> <p>{error.message}</p> </div> ); } return ( <> //you receive the overall status of the run, e.g. SUCCESS, FAIL <div>Run status: {run.status}</div> <div> {statuses.map((status) => { switch (status.key) { case "generating-memes": { const urls = status.data?.urls as string[] | undefined; return ( <div key={status.key}> // Will display: "Generating memes: loading" <p> {status.label}: {status.state} </p> //will render the memes as images {urls?.map((url) => <img key={url} src={url} />)} </div> ); } } })} </div> //this is what's returned from the run function {run.output && ( <code> <pre>{JSON.stringify(run.output, null, 2)}</pre> </code> )} </> );}