Search code examples
reduxredux-toolkitrtk-query

RTK Query selectFromResult causing unnecessary call to the API with undefined argument


I have a query with argument that can be an object or undefined. When I use function selectFromResult in my component, the endpoint is called with argument of undefined.

I understood that it should just get the value from the existing data not call the endpoint with no parameters.

export const getMessages = (
  build: EndpointBuilder<BaseQueryFn, string, string>
): QueryDefinition<
  IGetMessagesArgs | undefined,
  BaseQueryFn,
  string,
  IGetMessagesResponse
> =>
  build.query<IGetMessagesResponse, IGetMessagesArgs | undefined>({
    providesTags: ['Message'],
    query: (queryArg: IGetMessagesArgs | undefined) => {
      const paginationParamObject = {
        conversation: queryArg?.conversation,
        page: queryArg?.page,
      };
      const paginationQuery = serializeFlatObject(paginationParamObject, '?');
      const filterQuery = serializeFilters(queryArg?.filters);
      return {
        url: `/api/messages${paginationQuery}${filterQuery}`,
      };
    }
  });

In the parent component I'm calling it like this

const { data: messages } = useGetMessagesQuery(
    { conversation: conversation || '' },
    { skip: !conversation }
  );

And in the detials component

 const { message } = useGetMessagesQuery(undefined, {
    selectFromResult: ({ data }) => ({
      message: data?.items.find((el) => el.id === messageId),
    }),
  });

Is selectFromResult used wrong in this case?


Solution

  • selectFromResult just allows you to change the shape of result by using a selector function.
    But besides that, useGetMessagesQuery still works like useGetMessagesQuery works - no changes. So if you call useGetMessagesQuery with an undefined argument, it will start a request for an undefined argument.

    Your impression seems to be that once you add selectFromResult, it will just give you the result of a random cache entry for that endpoint - that is not the case.