Search code examples
redux-toolkitrtk-query

ReduxToolKit: correct way to use SelectFromResult options in a Query hook?


I am trying to understand how to correctly use SelectFromResult from the official documentation:

https://redux-toolkit.js.org/rtk-query/usage/queries#selecting-data-from-a-query-result

I have extended the Pokemon example to retrieve a filtered list of Pokemons ending in "saur" using SelectFromResult but the output results in a loss of error and isLoading data

live sandbox here: https://codesandbox.io/s/rtk-query-selectfromresult-vvb7l

relevant code here:

the endpoint extracts out the relevant data with a transformResponse:

    getAllPokemon: builder.query({
      query: () => `pokemon/`,
      transformResponse: (response: any) => {
        console.log("transformResponse", response);
        return response.results;
      }
    })

and the hook fails if i try to selectFromResult and I lose error and isLoading variables as they are no longer returned from the hook. If I comment out the SelectFromResult option they are then correctly returned.

export const PokemonList = () => {
  const { data, error, isLoading } = useGetAllPokemonQuery(undefined, {
    selectFromResult: ({ data }) => ({
      data: data?.filter((item: Pokemon) => item.name.endsWith("saur"))
    })
  });

  useEffect(() => {
    if (data) console.log("filtered result", data);
  }, [data]);

  return (
    <div>
      {data?.map((item: Pokemon) => (
        <p>{item.name}</p>
      ))}
    </div>
  );
};

My question: I dont want to lose fetch status when trying to filter results using the recommended method. How do I modify the above code to correctly SelectFromResult and maintain the correct error, isLoading, etc status values from the hook?


Solution

  • Solution found:

    I passed in and returned the additional required variables (and tested by adding a polling interval to allow me to disconnect to force and error)

      const { data, error, isLoading } = useGetAllPokemonQuery(undefined, {
        selectFromResult: ({ data, error, isLoading }) => ({
          data: data?.filter((item: Pokemon) => item.name.endsWith("saur")),
          error,
          isLoading
        }),
        pollingInterval: 3000,
      });