Skip to main content
Module

x/jotai/docs/utilities/async.mdx

👻 Primitive and flexible state management for React
Go to Latest
File
---title: Asyncnav: 3.03keywords: load,loadable,observable---
All atoms support async behavior such as async read or async write. However there are APIs for more control described here.
## loadable
If you don't want async atoms to suspend or throw to an error boundary (for example, for finer-grained control of loading and error logic), you can use the `loadable` util.
It would work the same way for any atom. Simply wrap your atoms with the `loadable` util. It returns a value with one of three states: `loading`, `hasData` and `hasError`.
```ts{ state: 'loading' | 'hasData' | 'hasError', data?: any, error?: any,}```
```jsximport { loadable } from "jotai/utils"
const asyncAtom = atom(async (get) => ...)const loadableAtom = loadable(asyncAtom)// Does not need to be wrapped by a <Suspense> elementconst Component = () => { const [value] = useAtom(loadableAtom) if (value.state === 'hasError') return <Text>{value.error}</Text> if (value.state === 'loading') { return <Text>Loading...</Text> } console.log(value.data) // Results of the Promise return <Text>Value: {value.data}</Text>}```
## atomWithObservable
Ref: https://github.com/pmndrs/jotai/pull/341
### Usage
```jsximport { useAtom } from 'jotai'import { atomWithObservable } from 'jotai/utils'import { interval } from 'rxjs'import { map } from 'rxjs/operators'
const counterSubject = interval(1000).pipe(map((i) => `#${i}`))const counterAtom = atomWithObservable(() => counterSubject)
const Counter = () => { const [counter] = useAtom(counterAtom) return <div>count: {counter}</div>}```
The `atomWithObservable` function creates an atom from a rxjs (or similar) `subject` or `observable`.Its value will be last value emitted from the stream.
To use this atom, you need to wrap your component with `<Suspense>`. Check out [guides/async](../guides/async.mdx).
### Initial value
`atomWithObservable` takes second optional parameter `{ initialValue }` that allows to specify initial value for the atom. If `initialValue` is provided then `atomWithObservable` will not suspend and will show initial value before receiving first value from observable. `initialValue` can be either a value or a function that returns a value
```jsconst counterAtom = atomWithObservable(() => counterSubject, { initialValue: 10,})
const counterAtom2 = atomWithObservable(() => counterSubject, { initialValue: () => Math.random(),})```
### Codesandbox
<CodeSandbox id="88pnt" />