29

How do you pass query parameters to the api using Redux Toolkit RTK Query?

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

const baseUrl = 'xxxxxxx';

export const postsApi = createApi({
  reducerPath: 'posts',
  baseQuery: fetchBaseQuery({ baseUrl }),
  endpoints: (builder) => ({
    getPostsByYear: builder.query({
      query: (start, end) => { // Why is 'end' always undefined???
        return {
          url: 'posts/',
          params: { start, end },
        };
      },
    }),
    getPosts: builder.query({
      query: () => 'posts/',
    }),

    getPostByID: builder.query({
      query: (name) => `posts/${name}`,
    }),
  }),
});

export const { useGetPostsQuery, useGetPostsByYearQuery, useGetPostByIDQuery } = postsApi;

When trying to pass parameters from the component only the start value seems to be recognised. year is updated by a select element within the <PostOptions/> component. It's using the useState hook. The value updates correctly and useGetPostsByYearQuery is called but the end parameter is always undefined. So, it seems I'm not defining the api endpoint correctly. Any advise? All I want it to do is send a request in the form http://xxx/posts?start=start&end=end.

I've even tried hard-coding a string value for the end parameter, e.g. useGetPostsByYearQuery(year, '2019'), but it still appears as undefined withing the api callback so I'm missing something more fundamental.

const Post = () => {
 
  const year = useSelector((state) => state.postOptions.year);
  const yearPlusOne = parseInt(year, 10) + 1;
  const { data, error, isLoading } = useGetPostsByYearQuery(year, yearPlusOne);

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.content}>
        <PostHeading />
        <PostOptions></PostOptions>
      </View>
    </SafeAreaView>
  );
};

export default Post;
1
  • 1
    not much to add to the answer from @slideshowp2, except this: query only ever takes one argument, that is why your end was giving you problems. The answer below shows very well how to get around that :) Commented Jun 28, 2021 at 8:41

1 Answer 1

61

The QueryArg is a generic type.

interface EndpointDefinitionWithQuery<
  QueryArg,
  BaseQuery extends BaseQueryFn,
  ResultType
> {
  query(arg: QueryArg): BaseQueryArg<BaseQuery>
}

See source code.

From the docs Defining Query Endpoints:

If the query callback needs additional data to generate the URL, it should be written to take a single argument. If you need to pass in multiple parameters, pass them formatted as a single "options object".

So you can declare the generic parameter QueryArg type for builder.query method like this:

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

const baseUrl = 'xxxxxxx';

export const postsApi = createApi({
  reducerPath: 'posts',
  baseQuery: fetchBaseQuery({ baseUrl }),
  endpoints: (builder) => ({
    getPostsByYear: builder.query<any, { start: string; end: string }>({
      query: (arg) => {
        const { start, end } = arg;
        console.log('arg: ', arg);
        return {
          url: 'posts/',
          params: { start, end },
        };
      },
    }),
  }),
});

export const { useGetPostsByYearQuery } = postsApi;

And pass the query arg like this:

import React from 'react';
import { useGetPostsByYearQuery } from './hooks';

export default function App() {
  const { data, error, isLoading } = useGetPostsByYearQuery({ start: '2019', end: '2021' });
  return <div>app</div>;
}

The log:

arg:  { start: '2019', end: '2021' }

version: "@reduxjs/toolkit": "^1.6.0"

Sign up to request clarification or add additional context in comments.

2 Comments

is it possible to pass query string param in mutation call ?
Pretty easy to avoid these dumb mistakes if we stop using type inference. That is just a stupid idea. Explicitly stating which type things are is verbose, but being verbose IS NOT A BAD THING.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.