A REST request with a toast status: Rest Pipeline JS + Toast Kit
A problem that shows up in any project with forms and an API: the user clicks "Save," a request goes out, and somewhere on screen "Saving…" needs to turn into "Saved" or an error message — without a hand-rolled try/catch/finally around every call site.
Rest Pipeline JS already gives you a client with retries and caching. Toast Kit gives you toast.promise(), which switches the notification type on its own based on how the promise settles. Together, zero manual loading-state wiring.
Client and call site
import { createRestClient } from 'rest-pipeline-js'
import { toast } from 'vue-toast-kit'
const client = createRestClient({
baseURL: 'https://api.example.com',
retry: { attempts: 2, delayMs: 500, backoffMultiplier: 2 },
auth: {
getToken: async () => localStorage.getItem('token') ?? '',
},
})
interface ProfileInput {
name: string
email: string
}
async function saveProfile(data: ProfileInput) {
return toast.promise(client.patch('/profile', data), {
loading: 'Saving profile…',
success: 'Profile saved',
error: (err) => `Couldn't save: ${(err as Error).message}`,
})
}toast.promise() returns the same promise it was handed — await saveProfile(data) in a form handler works exactly as usual, the user just sees a status along the way.
Why not just try/catch
The createRestClient retries fire BEFORE the promise ever reaches toast.promise() — if the first attempt fails over the network but the second (after delayMs) succeeds, the user never sees an error at all, just "Saving…" → "Saved." The toast reacts to the client's final outcome, not to every attempt inside it — retries and user feedback don't step on each other because they live at different layers.
What's next
- Add
circuitBreakertocreateRestClient— if the backend is fully down, error toasts won't fire on every click; the breaker rejects requests locally instead. See Rest Pipeline JS — overview. - For a reversible save, use
toast.undo()instead oftoast.promise(). See useToast, toast.promise, and toast.undo.