Search code examples
next.jsapolloapollo-client

How to extract query from `getServerSideProps` to separate helper file?


I've got several pages that I want to call a query inside of getServerSideProps to request the currentUser.

What I have currently is something like this:

import { NextPageContext } from 'next';
import { withAuth } from 'hoc/withAuth';
import { addApolloState, initializeApollo } from 'lib/apolloClient';
import { MeDocument } from 'generated/types';
import nookies from 'nookies';
import Profile from 'components/Profile';

const ProfilePage: React.FC = () => <Profile />;

export const getServerSideProps = async (
  context: NextPageContext
): Promise<any> => {
  // withAuth(context);

  const client = initializeApollo();
  const { my_token } = nookies.get(context);

  await client.query({
    query: MeDocument,
    context: {
      headers: {
        authorization: my_token ? `Bearer ${my_token}` : '',
      },
    },
  });

  return addApolloState(client, { props: {} });
};

export default ProfilePage;

This works, and I can verify in my Apollo devtools that the cache is being updated with the User.

When I try to move the Apollo initialization and query in to a separate file, the cache is never updated for some reason.

Inside of a withAuth.tsx file, I had something like this:

import { NextPageContext } from 'next';
import { addApolloState, initializeApollo } from 'lib/apolloClient';
import { MeDocument } from 'generated/types';
import nookies from 'nookies';

export const withAuth = async (context: any,) => {
  const client = initializeApollo();
  const { gc_token } = nookies.get(context);

  await client.query({
    query: MeDocument,
    context: {
      headers: {
        authorization: gc_token ? `Bearer ${gc_token}` : '',
      },
    },
  });

  return addApolloState(client, { props: {} });
};

With this, all I have to do is call withAuth() in the getServerSideProps. There are no errors, however the cache doesn't update.

How can I extract that code to a separate file correctly?


Solution

  • Thanks to @juliomalves in the comments, I simply forgot to return the withAuth function!

    Here's how it looks now:

    pages/index.tsx

    export const getServerSideProps = async (
      context: NextPageContext
    ): Promise<any> => await withAuth(context);
    

    withAuth.tsx

    /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
    import { getSession } from 'next-auth/client';
    import redirectToLogin from 'helpers/redirectToLogin';
    import { addApolloState, initializeApollo } from 'lib/apolloClient';
    import { MeDocument } from 'generated/types';
    import nookies from 'nookies';
    
    export const withAuth = async (context: any) => {
      const session = await getSession(context);
      const isUser = !!session?.user;
    
      // no authenticated session
      if (!isUser) redirectToLogin();
    
      const client = initializeApollo();
      const { token } = nookies.get(context);
    
      await client.query({
        query: MeDocument,
        context: {
          headers: {
            authorization: token ? `Bearer ${token}` : '',
          },
        },
      });
    
      return addApolloState(client, { props: {} });
    };