1

I need to make a request to a URL like this /common/path/:userId/specific/path/endpoints. /common/path is shared across many endpoints, and I don't want to put all of those queries in the same file. Ideally, I'd create a slice for /common/path/:userId/specific/path and its endpoints. I have userId when the store is created. Could I pass userId into the slice and put it in the baseUrl somehow?

Or am I approaching this wrong? Is there a better way? I can't change the structure of the URL.

EDIT: This is what I'm trying.

In MyFile.jsx

const store = configureStore({reducer: mySlice, userId})

In mySlice.js

export const mySlice = createApi({
    reducerPath: 'api',
    baseQuery: fetchBaseQuery({
        baseUrl: `/common/path/${state.userId}/specific/path`
    }),
    endpoints: {4 endpoints defined here}
})

But this doesn't work, because state and getState are not accessible when creating the baseUrl.

2
  • Is the base URL actually variable/dynamic, i.e. does it change after the API slice is created, or do you just need to know what it is when the API slice and store are created? "I have userId when the store is created" - leads me to think it's the latter case, and if so, is there any issue with just passing the computed baseURL string value when the slice and state are created? Do you have a minimal reproducible example of the code you are working with?
    – Drew Reese
    Commented Jan 23 at 16:04
  • Yes, the latter. I would like to pass the string value, but I don't understand how from the docs. I've updated my post with an example. Thank you! Commented Jan 23 at 17:23

1 Answer 1

1

But this doesn't work, because state and getState are not accessible when creating the baseUrl.

They are actually, but you need to create a custom baseQuery function.

See Implementing a custom baseQuery for details.

Create a base query function that accesses the Redux api to access the current state at the time a request is made to compute the desired baseUrl value that is then passed along to the actual fetchBaseQuery you are using.

Basic Example:

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

const baseQuery = (baseQueryArgs = {}) => async (
  fetchArgs = {},
  api,
  extraOptions = {},
) => {
  const { getState } = api;
  const state = getState();
  const baseUrl = `/common/path/${state.userId}/specific/path`;

  return fetchBaseQuery({
    ...baseQueryArgs,
    baseUrl,
  })(fetchArgs, api, extraOptions);
};
export const mySlice = createApi({
  reducerPath: 'api',
  baseQuery: baseQuery(),
  endpoints: {/* 4 endpoints defined here */}
});

If you wanted this to be a little more robust you could pass a baseUrl string with some placeholder text that is replaced in baseQuery.

Example:

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

const baseQuery = (baseQueryArgs = {}) => async (
  fetchArgs = {},
  api,
  extraOptions = {},
) => {
  const { getState } = api;
  const state = getState();
  const baseUrl = baseQueryArgs.baseUrl.replace("{{userId}}", state.userId);

  return fetchBaseQuery({
    ...baseQueryArgs,
    baseUrl,
  })(fetchArgs, api, extraOptions);
};
export const mySlice = createApi({
  reducerPath: 'api',
  baseQuery: baseQuery({
    baseUrl: "/common/path/{{userId}}/specific/path",
  }),
  endpoints: {/* 4 endpoints defined here */}
});

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.