-1

I would like to supply Dates as arguments to my RTK Queries. For instance, I have an interface like so that I supply to my queries:

export interface ScheduleIdentifier {
  code: string;
  date: Date;
}

I have endpoints like so that take a Date (via ScheduleIdentifier or the like):

export interface GetScheduleVariables {
  schedule: ScheduleIdentifier;
}

export const MyApi = createApi({
  reducerPath: 'myApi',
  baseQuery: fetchBaseQuery({ baseUrl }), 
  endpoints: (builder) => ({
    getSchedule: builder.query<GetSchedule, GetScheduleVariables>({
      // attempt to make RTK Query happy about the date...
      serializeQueryArgs: (params) => {
        return JSON.stringify({
          schedule: {
            code: params.queryArgs.schedule.code,
            date: params.queryArgs.schedule.date.toISOString()
          }
        });
      },
      query: (params) => ({
        ...
      })
    }),
  })
});

Unfortunately - even despite the custom serializeQueryArgs function - I get a an error like so in the console:

A non-serializable value was detected in the state, in the path: myApi.queries.{"schedule":{"code":"5ea5d2ec-59f6-4ed1-a9d2-fed92e532c73","date":"2023-07-27T00:00:00.000Z"},"filter":{}}.originalArgs.schedule.date. Value: Date Wed Jul 26 2023 17:00:00 GMT-0700 (Pacific Daylight Time)

Take a look at the reducer(s) handling this action type: myApi/executeQuery/pending.

(See https://redux.js.org/faq/organizing-state#can-i-put-functions-promises-or-other-non-serializable-items-in-my-store-state)

EDIT: Adding Stack Trace

 index.js:1191
   e index.js:1191
   Redux 19
   React 3
   query index.tsx:148
   ScheduleViewPage index.tsx:223
   React 5
   unstable_runWithPriority scheduler.development.js:401
   React 4
   unstable_runWithPriority scheduler.development.js:401
   React 6
   render index.tsx:34
   tsx index.tsx:36
   tsx main.chunk.js:144741
   Webpack 7

I've googled around, but I haven't been able to find a clear answer on how to approach this. Please advise - thank you!

  • 1
    I think the error is informing you that you've stored a non-serializable value ***in the store***, not that you are using a non-serializable cache key. Can you [edit] to include the complete error message and any accompanying error stacktrace? – Drew Reese Aug 02 '23 at 20:05
  • @DrewReese Done! I believe you are correct that the error is getting thrown from the value being placed in the store. Not sure what tools RTK Query gives me to address this. I feel like there should be a transformRequest parameter, like there is a transformResponse parameter. I may end up just creating a wrapper around the useGetSchedule and useLazyGetSchedule functions locally as a work-around. – Ryan Pierce Williams Aug 02 '23 at 22:16
  • What is the query you are making, what is the response value? – Drew Reese Aug 02 '23 at 22:17
  • I have a few requests that use the same Date, some are POSTs and others GETs. The requests themselves complete successfully; I just want to fix the console errors. In the simplest case, the useGetScheduleQuery is formatting the request like so: `query: (params) => ({ url: '/schedules?${createScheduleIdentifierSearchParams(params.schedule).toString()}', method: 'GET', }),` Thus it would end up being something like `/schedules?date=2023-08-02&code=asdf-145-sd` The response value is a json object containing the serialized Schedule. – Ryan Pierce Williams Aug 02 '23 at 22:34

1 Answers1

0

This isn't ideal (there should be a configuration option for endpoints to serialize the args prior to hitting the store at all, and not just the RTK Query cache), but I was able to hide the console errors my turning off the serializable check under the store configuration for all my Apis like so:

const apis = [
  MyApi,
  MyOtherApi,
  ...
];

const serializableCheck:SerializableStateInvariantMiddlewareOptions = {
  ignoredPaths: apis.map(_ => _.reducerPath)
}

export const store = configureStore({
  reducer: apis.reduce((result, curr) => 
    Object.assign(result, { [curr.reducerPath]: curr.reducer }), {}
  ),

  middleware: (getDefaultMiddleware) =>
    apis.reduce<MiddlewareArray<any>>((result, curr) => 
      result.concat(curr.middleware), getDefaultMiddleware({ serializableCheck }))
});

I'll leave the question open for now, however, in case someone is able to find a better solution.