jsonreactjsreact-reduxnext.jsnext-redux-wrapper

Unable to fetch data from server due to serialization problem using NextJS?


I'm currently using axios and NextJS.

I currently have this code in my component:

export async function getServerSideProps(context) {
  const data = await getVideo(context.query.id);

  console.log('data: ', data);
  // console.log('context: ', context);
  console.log('context params: ', context.params);
  console.log('context query: ', context.query);

  if (!data) {
    return { notFound: true };
  }

  return {
    props: {
      videoId: context.params.id,
      videoSlug: context.params.slug,
      videoContent: data
    }
  };
}

This getserverSideProps call the function of getVideo which looks exactly like this:

export const getVideo = (id) => async (dispatch) => {
  dispatch({ type: CLEAR_VIDEO });
  try {
    console.log('Action file: ', id);
    const res = await api.get(`/videos/${id}`);

    return dispatch({
      type: GET_VIDEO,
      payload: res.data
    });
  } catch (err) {
    dispatch({
      type: VIDEO_ERROR,
      payload: { msg: err.response?.statusText, status: err.response?.status }
    });
  }
};

Said function goes through my api function to make requests to backend:

import axios from 'axios';
import { LOGOUT } from '../actions/types';
import { API_URL } from '../config';

const api = axios.create({
  baseURL: `${API_URL}/api/v1`,
  headers: {
    'Content-Type': `application/json`
  }
});
/**
 intercept any error responses from the api
 and check if the token is no longer valid.
 ie. Token has expired
 logout the user if the token has expired
**/

api.interceptors.response.use(
  (res) => {
    res;
    console.log('Res: ', res.data);
  },
  (err) => {
    if (err?.response?.status === 401) {
      typeof window !== 'undefined' &&
        window.__NEXT_REDUX_WRAPPER_STORE__.dispatch({ type: LOGOUT });
    }
    return Promise.reject(err);
  }
);

export default api;

It works great when doing POST, PUT,PATCH requests.

As you can see, I'm doing a console.log('data: ',data) but it returns [AsyncFunction (anonymous)] whenever I read the terminal; on the other hand, the front-end returns this error:

Server Error Error: Error serializing .videoContent returned from getServerSideProps in "/videos/[id]/[slug]". Reason: function cannot be serialized as JSON. Please only return JSON serializable data types.

Does anyone knows how to solve this?

NOTE: I'm using react-redux, redux and next-redux-wrapper.


Solution

  • That is because your getVideo function returns another function. The right way to call it would be:

      const data = await getVideo(context.query.id)()//<- pass in the dispatch here
    

    But you should not use redux in the backend like that. I think you can completely remove it.

    export const getVideo async (id) => {
      try {
        console.log('Action file: ', id);
        const res = await api.get(`/videos/${id}`);
        return res.data
        });
      } catch (err) {
         return { msg: err.response?.statusText, status: err.response?.status }
        }
    };
    // call
    const data = await getVideo(context.query.id)