Skip to main content

Custom Actions, Filters and Optimistic Operations

Custom Actions

You can define domain-specific actions:

const usersManager = new QueryManager<User>({
// ... basic configurations
actions: {
// Action to activate user
async activate(manager, userId: number) {
await api.post(`/users/${userId}/activate/`)
// Update item in cache
await manager.refreshItem(userId)
// Can update other related managers
notificationsManager.refresh()
},

// Action to send email
async sendEmail(manager, userId: number, message: string) {
await api.post(`/users/${userId}/send-email/`, { message })
return 'Email sent successfully'
},
},
})

// Using actions
function UserCard({ user }: { user: User }) {
const { activate, sendEmail } = usersManager.actions

const handleActivate = () => {
activate(user.id)
}

const handleSendEmail = async () => {
const result = await sendEmail(user.id, 'Hello!')
alert(result)
}

return (
<div>
<h3>{user.name}</h3>
<button onClick={handleActivate}>Activate</button>
<button onClick={handleSendEmail}>Send Email</button>
</div>
)
}

Filters and Metadata

// Using filters
const { items } = usersManager.useList({
filter: {
status: 'active',
role: 'admin',
search: 'john',
},
})

// Custom metadata
const usersManager = new QueryManager<User, FilterArgs, UserMeta>({
// ... configurations
initialMeta: {
totalActiveUsers: 0,
lastSync: new Date(),
},
})

// Updating metadata
usersManager.setOptions({
meta: {
totalActiveUsers: 150,
},
})

Optimistic Operations

Optimistic operations show changes in the UI before server confirmation:

// Global configuration in manager
const usersManager = new QueryManager<User>({
// ... other configurations
creation: {
optimistic: true,
appendTo: 'start', // Add to beginning of list
},
update: {
optimistic: true,
},
deletion: {
optimistic: true,
},
})

// Or per individual operation
const { create } = usersManager.useCreate({
optimistic: true,
appendTo: 'end', // Overrides global configuration
})