Reputation: 48
I have an application that uses Next.js, Redux, RTK Query and next-redux-wrapper and I'm having an issue with cookies not being available in a Next.js API route once store.dispatch(getMedications.initiate())
runs - the cookie is undefined on server render, but can be read fine once the page loads.
On the same page I have a useGetMedicationsQuery
hook that runs, which works completely fine and can access the cookies when the query is run, however whenever the store.dispatch(getMedications.initiate())
query is run server side i.e. in the getServerSideProps
the token
cookie is undefined
.
/pages/api/medications/get-medications.js
import axios from 'axios';
export default async (req, res) => {
const SERVICE_HOST = process.env.SERVICE_HOST;
const cookies = req.cookies;
const token = cookies.token; // undefined when initiated via store.dispatch(getMedications.initiate())
try {
const response = await axios.get(`${SERVICE_HOST}/patient/medications`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
res.status(200).json(response.data.data);
} catch(error) {
res.status(500).json(error.response);
}
}
/services/medications.js
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/dist/query/react";
import { HYDRATE } from "next-redux-wrapper";
export const medicationApi = createApi({
reducerPath: "medicationApi",
baseQuery: fetchBaseQuery({
baseUrl: 'http://localhost:3001/api/medications/',
}),
keepUnusedDataFor: 3600,
extractRehydrationInfo(action, { reducerPath }) {
if (action.type === HYDRATE) {
return action.payload[medicationApi];
}
},
tagTypes: ['Medications'],
endpoints: (build) => ({
getMedications: build.query({
query: () => `get-medications/`,
providesTags: () => ['Medications']
}),
}),
})
export const {
useGetMedicationsQuery,
util: { getRunningOperationPromises }
} = medicationApi;
export const { getMedications } = medicationApi.endpoints;
/pages/medications.js
export const getServerSideProps = wrapper.getServerSideProps(
(store) => async ({ req, res }) => {
const WEBSITE_URL = process.env.WEBSITE_URL;
const SERVICE_HOST = process.env.SERVICE_HOST;
const COOKIE_DOMAIN = process.env.COOKIE_DOMAIN || '';
const cookies = cookie.parse(req.headers.cookie || '');
const token = cookies.token;
if (!token) {
return {
redirect: {
destination: `${WEBSITE_URL}/login/${queryString(req.url)}`,
permanent: false,
}
}
}
try {
... some stuff
store.dispatch(getMedications.initiate());
await Promise.all(getRunningOperationPromises());
return {
props: {
}
}
} catch(error) {
createTokenCookie(res, COOKIE_DOMAIN, '')
return {
redirect: {
destination: `${WEBSITE_URL}/login/`,
permanent: false,
}
}
}
}
);
Upvotes: 0
Views: 4842
Reputation: 11
extractRehydrationInfo(action, { reducerPath }) {
if (action.type === HYDRATE) {
return action.payload[medicationApi];
}
},
this should be changed to
extractRehydrationInfo(action, { reducerPath }) {
if (action.type === HYDRATE) {
return action.payload[reducerPath];
}
},
Upvotes: 1