Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Tags: Mark stall data after create/edit mutation #1098

Merged
merged 2 commits into from
Jul 11, 2023
Merged

✨ Tags: Mark stall data after create/edit mutation #1098

merged 2 commits into from
Jul 11, 2023

Conversation

gildub
Copy link
Contributor

@gildub gildub commented Jul 6, 2023

@codecov
Copy link

codecov bot commented Jul 6, 2023

Codecov Report

Patch coverage: 18.60% and project coverage change: -0.07 ⚠️

Comparison is base (573bce2) 44.11% compared to head (28b4237) 44.04%.

❗ Current head 28b4237 differs from pull request most recent head 83a6edb. Consider uploading reports for the commit 83a6edb to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1098      +/-   ##
==========================================
- Coverage   44.11%   44.04%   -0.07%     
==========================================
  Files         177      177              
  Lines        4477     4493      +16     
  Branches      997     1007      +10     
==========================================
+ Hits         1975     1979       +4     
- Misses       2491     2503      +12     
  Partials       11       11              
Flag Coverage Δ
unitests 44.04% <18.60%> (-0.07%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
client/src/app/queries/tags.ts 20.27% <0.00%> (ø)
.../shared/components/FilterToolbar/FilterControl.tsx 37.50% <ø> (ø)
client/src/app/layout/SidebarApp/SidebarApp.tsx 26.66% <16.00%> (-2.97%) ⬇️
...d/components/FilterToolbar/SelectFilterControl.tsx 13.63% <28.57%> (+3.11%) ⬆️
...ponents/FilterToolbar/MultiselectFilterControl.tsx 10.93% <40.00%> (+2.60%) ⬆️

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Member

@sjd78 sjd78 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a suggestion

@@ -54,10 +54,12 @@ export const useCreateTagMutation = (
onSuccess: (res) => {
onSuccess(res);
queryClient.invalidateQueries([TagsQueryKey]);
queryClient.invalidateQueries([TagCategoriesQueryKey]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since most of the mutations seem to need to invalidate both queries, why not just have a helper to make sure things are handled that same way for all?

E.g.

const useInvalidatingMutation = <T>(
  mutationFn: MutationFunction<T, T>,
  onSuccess: (res: any) => void,
  onError: (err: AxiosError) => void
) => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn,
    onSuccess: (res) => {
      onSuccess(res);
      queryClient.invalidateQueries([TagsQueryKey]);
      queryClient.invalidateQueries([TagCategoriesQueryKey])
    },
    onError: (err: AxiosError) => {
      onError(err);
      queryClient.invalidateQueries([TagsQueryKey]);
      queryClient.invalidateQueries([TagCategoriesQueryKey])
    },
  });
}

And then this mutation can just look like:

export const useCreateTagMutation = (
  onSuccess: (res: any) => void,
  onError: (err: AxiosError) => void
) => {
  return useInvalidatingMutation(createTag, onSuccess, onError);
};

Copy link
Collaborator

@mturley mturley Jul 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say we should perhaps include an additional mutationOptions object that is a Partial<UseMutationOptions> and gets spread into the inner useMutation, or perhaps just have the arguments for useInvalidatingMutation be themselves the same UseMutationOptions object, but the onSuccess and onError just get overridden? TypeScript generics might get weird I suppose.

Also, we may want to consider using compound query key arrays that contain some common element we can pass to invalidate any query that has to do with tags. The queryKey can be an array with any number of elements to identify the query, and if any of those elements is passed into invalidateQueries it will invalidate all matching queries. https://tanstack.com/query/v4/docs/react/guides/query-keys

That would at least mean we can do a single queryClient.invalidateQueries([TagsQueryKey]) if we just include TagsQueryKey along with TagCategoriesQueryKey in the tag categories query hook's key. It still doesn't prevent all the duplication @sjd78's suggestion would address though, so maybe we can do both.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @sjd78 and @mturley , for the review.

I've pushed an update using compound query key which simplifies and therefore it doesn't need to use an helper.
Effectively on the tags page, the tags are depending upon the tagCategories since we're displaying the tags for each tag category they belong to, therefore when a tag is touched (Created/updated/deleted) then we want to invalidate the same query key we use for fetching the tagCategories.

@gildub gildub requested a review from sjd78 July 10, 2023 15:32
Signed-off-by: Gilles Dubreuil <gdubreui@redhat.com>
Signed-off-by: Gilles Dubreuil <gdubreui@redhat.com>
Copy link
Member

@sjd78 sjd78 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See inline comments

@@ -53,11 +53,11 @@ export const useCreateTagMutation = (
mutationFn: createTag,
onSuccess: (res) => {
onSuccess(res);
queryClient.invalidateQueries([TagsQueryKey]);
queryClient.invalidateQueries([TagCategoriesQueryKey, TagsQueryKey]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I debugged through the react-query code -- this only invalidates the query that matches both keys.

Effectively, this change invalidates the useFetchTagCategories query now instead of the useFetchTags query.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT, the only way to invalidate 2 queries is to either:

  1. call invalidate twice with exactly matching queryKey, or
  2. setup multiple values in the initial queryKey and use one of those across all queries you want to invalidate at the same time.

For example:

export const useFetchTags = () => {
  const { data, isLoading, error, refetch } = useQuery({
    queryKey: ["allTags", TagsQueryKey],
    queryFn: getTags,
    onError: (error: AxiosError) => console.log("error, ", error),
  });
  return {
    tags: data || [],
    isFetching: isLoading,
    fetchError: error,
    refetch,
  };
};

export const useFetchTagCategories = () => {
  const { data, isLoading, error, refetch } = useQuery({
    queryKey: ["allTags", TagCategoriesQueryKey],
    queryFn: getTagCategories,
    onError: (error: AxiosError) => console.log("error, ", error),
  });
  return {
    tagCategories: data || [],
    isFetching: isLoading,
    fetchError: error,
    refetch,
  };
};

export const useCreateTagMutation = (
  onSuccess: (res: any) => void,
  onError: (err: AxiosError) => void
) => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: createTag,
    onSuccess: (res) => {
      onSuccess(res);
      queryClient.invalidateQueries(["allTags"]);
    },
    onError: (err: AxiosError) => {
      onError(err);
      queryClient.invalidateQueries(["allTags"]);
    },
  });
};

The extra "allTags" shouldn't do anything to the query itself other than make it easier to partial match on the invalidateQueries() call

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, option 2 here is what I meant above.

@gildub gildub requested review from sjd78 and mturley July 11, 2023 18:28
Copy link
Member

@sjd78 sjd78 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With invalidation only needed on the tag category query, this change LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants