Skip to main content

Loading + progress states

When Interval actions aren't waiting on input from the person running the action, they're executing your action function's code. If this code does a lot of work or takes a while to execute, it can be helpful to express a loading state to the person running the action and provide updates on progress in real time. The ctx.loading functions allow you to display loading spinners and provide detailed context on the work your action is doing.

import { Action, ctx } from "@interval/sdk";

export default new Action(async () => {
await ctx.loading.start({
label: "Counting all the things",
description: "This may take a while",
});

// ... arduous logic here
});

When a loading state is started, a spinner will be displayed to the person running the action. This spinner will be cleared when any subsequent input is requested via I/O methods or when the action completes.

You can update the loading message at any point in your action's execution via ctx.loading.update.

import { Action, ctx } from "@interval/sdk";

export default new Action(async () => {
await ctx.loading.start({
label: "Counting all the widgets",
description: "This may take a while",
});

// ... arduous logic here

await ctx.loading.update({
label: "Counting all the widgets again",
description: "Just to double check",
});
});

For simple loading states, you can just pass a string to ctx.loading.start (or ctx.loading.update) as a shorthand syntax for specifying only label.

import { Action, ctx } from "@interval/sdk";

export default new Action(async () => {
await ctx.loading.start("This may take a while");
// ... arduous logic here
});

Progress‚Äč

Interval supports providing granular progress updates on your loading states. If ctx.loading.start is called with the itemsInQueue option to specify the total number of items being operated on (i.e. within a loop), the Interval dashboard will display a progress bar instead of a loading spinner.

You can then dynamically update the overall progress of the loading state by calling ctx.loading.completeOne after your action executes the work required for each item.

import { Action, ctx } from "@interval/sdk";

export default new Action(async () => {
await ctx.loading.start({
label: "Migrating users",
description: "Enabling edit button for selected users",
itemsInQueue: 100,
});

for (const user of users) {
// ... migration logic
await ctx.loading.completeOne();
}
});
Did this section clearly explain what you wanted to learn?
On this page