useDoc ​

useDoc fetches one Frappe document and keeps it up to date. Every useDoc for the same document shares one copy, so a change made through one shows in all of them.

Basic example ​

vue
<template>
  <div v-if="todo.doc">
    {{ todo.doc.description }}
  </div>
  <Button @click="todo.setValue.submit({ status: 'Closed' })">Close</Button>
</template>

<script setup>
import { useDoc } from 'frappe-ui'

const todo = useDoc({
  doctype: 'ToDo',
  name: 'TODO-0001',
})
</script>

Follow the route ​

Pass name as a getter or a ref. When it changes, useDoc fetches the new document:

vue
<script setup>
import { useRoute } from 'vue-router'
import { useDoc } from 'frappe-ui'

const route = useRoute()
const todo = useDoc({
  doctype: 'ToDo',
  name: () => route.params.name,
})
</script>

Run document methods ​

methods turns whitelisted methods of the document into members you call with submit():

vue
<script setup>
import { useDoc } from 'frappe-ui'

const todo = useDoc({
  doctype: 'ToDo',
  name: 'TODO-0001',
  methods: {
    // short form: the server method name
    markDone: 'mark_done',
    // full form: useCall options plus the method name
    reassign: {
      name: 'reassign',
      onSuccess: () => console.log('reassigned'),
    },
  },
})

todo.markDone.submit()
todo.reassign.submit({ allocated_to: '[email protected]' })
</script>

The full form takes the useCall options except url, baseUrl, immediate and refetch. method defaults to 'POST'. A method runs only when you call submit().

A key that matches a built-in member, such as doc, reload or setValue, throws an error. Pick another key and keep the server name in name: { runSetValue: { name: 'set_value' } }.

Options ​

NameTypeDefaultDescription
doctypestringrequiredThe DocType of the document.
nameMaybeRefOrGetter<string>requiredThe document name. A ref or getter makes useDoc follow it.
methodsRecord<string, string | object>{}Document methods to add as members. See Run document methods.
immediatebooleantrueFetches the document as soon as name has a value.
staleOnErrorbooleanfalseKeeps the saved copy of a document older than five minutes, so it can still show if a fetch fails.
transform(doc) => docChanges the document before doc returns it.
urlstring/api/v2/document/<doctype>/<name>Replaces the URL of the fetch. setValue and delete still use the default URL.
baseUrlstring''A prefix for every request URL.

Return value ​

NameTypeDescription
docTDoc | nullThe document, or null before it has loaded.
errorError | nullThe error from the last fetch.
loadingbooleantrue while the document is being fetched. Also available as isFetching.
isFinishedbooleantrue once the current fetch has settled, with or without an error.
canAbortbooleantrue while a fetch that can be aborted is in flight.
abortedbooleantrue if the last fetch was aborted.
reload()() => PromiseFetches the document again. Resolves even if it fails, so check error. Also available as execute() and fetch().
abort()() => voidAborts the fetch in flight.
setValueuseCall resultsetValue.submit(values) saves the given fields and puts the saved document in doc. Rejects if it fails.
deleteuseCall resultdelete.submit() deletes the document and removes it from every useDoc and useList. Rejects if it fails.
onSuccess(callback)(callback: (doc) => void) => () => voidRuns callback after each successful fetch by this useDoc. Returns a function that removes it.
one per methods keyuseCall resultRuns that document method with submit(params). Rejects if it fails.

setValue, delete and the methods members have the same members as a useCall result, but each submit() sends its own request, so two saves at the same time do not cancel each other.

Errors ​

setValue.submit(), delete.submit() and the methods members reject when they fail, so catch the error. reload() resolves and sets error. See Errors for the rule and the error classes.

js
try {
  await todo.setValue.submit({ status: 'Closed' })
} catch (error) {
  toast.error(error.message)
}

Shared cache ​

Every useDoc, and every useList row, for the same doctype and name reads from one shared store. A setValue or delete through any of them updates the document everywhere it shows. A document created with useNewDoc is in the store as soon as its submit() resolves.

Documents are also saved in IndexedDB. On the next page load, useDoc shows the saved copy while it fetches the current one. Each user has their own saved copies: see One cache per user.