T
TanStack3y ago
other-emerald

QueryObserver multiple keys

How i can observe any task? I want to know which task is created, updated or deleted. i use mutations to create, update, delete tasks, maybe the tan stack query has its own mutation observer? (изменено)
No description
7 Replies
other-emerald
other-emeraldOP3y ago
Up
variable-lime
variable-lime3y ago
Not sure I understand the question. Can you elaborate?
other-emerald
other-emeraldOP3y ago
// Think of A as a kind of event emitter.
export const taskObserver = A(undefined);

taskObserver.on('list', (data) => console.log('list', data));
taskObserver.on('upsert', (data) => console.log('upsert', data));
taskObserver.on('remove', (data) => console.log('remove', data));

// I have two queries - tasks and task
export const useTasksQuery = () =>
useQuery({
queryKey: ['tasks'],
queryFn: client.task.list.query,
enabled: isAuthenticated,
onSuccess: (data) => {
taskObserver.dispatch('list', data);
},
});


export const useTaskQuery = (id: Ref<string>) => // Yes, i use vue adapter :)
useQuery({
queryKey: ['task', id],
queryFn: () =>
client.task.list
.query()
.then((tasks) => tasks.find((task) => task.id === id.value)),
});

// And two mutations - upsert (insert or replace) and remove

export const upsertTask = () =>
useMutation({
mutationFn: client.task.upsert.mutate,
onMutate: async (newTask) => {
// some optimistic update stuff...
// It's an awful 30 lines, not now.
},
onSuccess: (data, _, context) => {
if (!context?.previousTask) {
queryClient.setQueryData(['tasks'], (old) => [...old, data]);
}
return taskObserver.dispatch('upsert', data);
}
});

export const removeTask = () =>
useMutation({
mutationFn: client.task.remove.mutate,
onMutate: async (removedTask) => {
// same stuff...
},
onSuccess: (_, res) => taskObserver.dispatch('remove', res.id),
});
// Think of A as a kind of event emitter.
export const taskObserver = A(undefined);

taskObserver.on('list', (data) => console.log('list', data));
taskObserver.on('upsert', (data) => console.log('upsert', data));
taskObserver.on('remove', (data) => console.log('remove', data));

// I have two queries - tasks and task
export const useTasksQuery = () =>
useQuery({
queryKey: ['tasks'],
queryFn: client.task.list.query,
enabled: isAuthenticated,
onSuccess: (data) => {
taskObserver.dispatch('list', data);
},
});


export const useTaskQuery = (id: Ref<string>) => // Yes, i use vue adapter :)
useQuery({
queryKey: ['task', id],
queryFn: () =>
client.task.list
.query()
.then((tasks) => tasks.find((task) => task.id === id.value)),
});

// And two mutations - upsert (insert or replace) and remove

export const upsertTask = () =>
useMutation({
mutationFn: client.task.upsert.mutate,
onMutate: async (newTask) => {
// some optimistic update stuff...
// It's an awful 30 lines, not now.
},
onSuccess: (data, _, context) => {
if (!context?.previousTask) {
queryClient.setQueryData(['tasks'], (old) => [...old, data]);
}
return taskObserver.dispatch('upsert', data);
}
});

export const removeTask = () =>
useMutation({
mutationFn: client.task.remove.mutate,
onMutate: async (removedTask) => {
// same stuff...
},
onSuccess: (_, res) => taskObserver.dispatch('remove', res.id),
});
@TkDodo 🔮 There are several modules in my project that want to be notified when a task changes. For example NotificationModule (remove the old notification and schedule a new one if task.datetime has changed, but I don't want to reschedule all notifications if one task has changed, I want more performance). To notify my modules, I need to insert (for my opinion) code which complicate query declaration. I read the docs several times and found awesome QueriesObserver it’s what I want, but for mutations, not query. What can you advise for this situation, how to remove the use of external event emitter and notify my modules? P.s. Thanks for the blog, I'm reading "Inside React Query", very impressed with the content, I think I understand the terms and internal code a much better than before.
flat-fuchsia
flat-fuchsia3y ago
MutationCache | TanStack Query Docs
The MutationCache is the storage for mutations. Normally, you will not interact with the MutationCache directly and instead use the QueryClient.
other-emerald
other-emeraldOP3y ago
@donysukardi is a cache, not an observer. Why should I create an empty mutationcache instance and then call the subscribe method?
flat-fuchsia
flat-fuchsia3y ago
You can retrieve the mutationCache from queryClient and then subscribe to mutation events
other-emerald
other-emeraldOP3y ago
Thank you 😊 I was wrong.

Did you find this page helpful?