useCall
useCall, useDoc, useList, useDoctype and useNewDoc are the recommended data-fetching layer for new code. If you're maintaining an app still on the older resource API, see Resources — it stays fully supported through 1.x.
useCall calls a whitelisted Frappe method or a REST endpoint and gives you back a reactive object with the response, loading and error state.
Basic example
<template>
<Button @click="ping.reload()" :loading="ping.loading"> Ping </Button>
<pre>{{ ping.data }}</pre>
</template>
<script setup>
import { useCall } from 'frappe-ui'
const ping = useCall({
url: '/api/method/ping',
})
</script>By default the request fires immediately and uses GET.
Submitting with params
Set method and call submit() for anything that isn't a plain GET:
<script setup>
import { useCall } from 'frappe-ui'
const renameTodo = useCall({
url: '/api/method/frappe.client.rename_doc',
method: 'POST',
immediate: false,
})
async function rename(name, newName) {
await renameTodo.submit({
doctype: 'ToDo',
old_name: name,
new_name: newName,
})
}
</script>Options
url— the endpoint to call. A REST path or a whitelisted method dotted path. Accepts aRef<string>for a URL that changes reactively.method— the HTTP method:'GET' | 'POST' | 'PUT' | 'DELETE'. Defaults to'GET'.params— the request params. Either a plain object, or a function returning one, read fresh on every request — use the function form so reactive values inside are re-read on each call.immediate— fire the first request automatically whenuseCallis set up. Defaults totrue.refetch— automatically fire a new request whenever a reactiveurlorparamsdependency changes. Defaults tofalse.baseUrl— prefix prepended tourl. Useful when the Frappe site isn't served from the same origin as the frontend.initialData— the valuedataholds before the first response arrives.cacheKey— a string, or array of primitives, that persists the response in memory and IndexedDB under that key. A seconduseCallwith the samecacheKeyshows the cached value immediately while it refetches in the background.staleOnError— whentrueandcacheKeyis set, a failed refetch keeps showing the last cacheddatainstead of clearing it. Does not apply when the failure is a Frappe error response (FrappeResponseError) — that still clears the cache. Defaults tofalse.transform— receives the raw response data and returns the valuedatashould hold. Returnundefinedto leave the response untouched.beforeSubmit— runs before asubmit()call sends its request. Use it for side effects like clearing a previous validation message; a normal return does not stop the request from being sent. If it throws, the request is not sent andsubmit()rejects.onSuccess— called with the response data after a successful request.onError— called with the error after a failed request.
Return value
data— the response data, ornullbefore the first successful response.error— the error from the last request, ornull.loading(aliasisFetching) —truewhile a request is in flight.isFinished—trueonce the current request has settled, either way.params— the params that were sent with the last request.url— the fully resolved URL, includingbaseUrland, forGETrequests, the serialized query string.promise— the in-flight request's promise. Resolves (it never rejects) once the request settles, whether it succeeded or failed — checkerrorafter awaiting it.canAbort—truewhile a request that can still be aborted is in flight.aborted—trueif the last request was aborted.execute()(aliasesfetch(),reload()) — fires a request using the currentparams, ignoringimmediate/refetch. Returns a promise that resolves with the response data, or rejects if the request fails.submit(params?)— runsbeforeSubmit, then sends a request with the given params (or the configuredparamsif omitted). Resolves with the response data, or rejects with the error.reset()— clears any params set by a previoussubmit()call.abort()— aborts the in-flight request.
Errors
A Frappe error response rejects submit()/execute() and sets error to a FrappeResponseError, which carries title, type, exception and indicator from the server's response — narrow a catch block with error instanceof FrappeResponseError to read them.
Caching
Pass cacheKey to persist the response. The cached value is read from IndexedDB and shown immediately on the next useCall with the same key, while a fresh request runs in the background and replaces it once it resolves.
const todo = useCall({
url: '/api/method/frappe.client.get',
params: { doctype: 'ToDo', name: 'todo-1' },
cacheKey: ['todo', 'todo-1'],
})