Search code examples
reduxnext.jsredux-toolkitrtk-query

Redux toolkit mutation past post body as string and not JSON using TS


Stack:

  • NextJS
  • TypeScript
  • Redux-Toolkit
  • For

Here are the parts of the code that works with JS:

Page:

const onSubmit = async (values: UserPayload) => {

    let newValues = {
      ...values,
      birthDate: birthDate.toISOString()
    }

    if (user && user.id) {
      newValues.id = user.id;

    } else {
      console.log("saving user", newValues);
      try {
        await createUser(newValues).unwrap();
        console.log('fulfilled', newValues)
      } catch (error) {
        console.error('rejected', error);
      }
    }
  }

// Redux mutation

createUser: build.mutation<UserPayload, UserPayload>({
  query: (body: UserPayload) => ({
    url: `/users`,
    method: 'POST',
    body: {...body}
  }),
  invalidatesTags: [{type: "User", id: "LIST"}]
}),

// NextJS API

export default async function handler(
    req: NextApiRequest,
    res: NextApiResponse<Partial<UserPayload> | UserPayload[]>
) {

  console.log('req params', req.query);
  console.log('req body', req.body);

// Output of console.log

req params {}
req body [object Object]
saving [object Object]

This same code works with JS. Note that when we print the user object inside the mutation code, it will print the object as JSON correctly. Why is it converted to string inside the body of the post request?


Solution

  • I found the problem. I've set the content-type to application/hal+json, should be application/json. Here's the baseQuery:

    fetchBaseQuery({
        baseUrl: `http://localhost:3000/api/`,
        prepareHeaders: (headers) => {
          headers.set('Authorization', `Bearer ${token}`);
          headers.set('Content-Type', 'application/json');
    
          return headers;
        }
      });