'React getInitialProps not running entire function on page refresh

Edit: figured it out - for some reason if I manually copy paste the getReviewOffice/getUsers into my get initial props it works fine shrug. I looked into the way I was importing the functions and it looks fine/works for the initialState args.

I'm not very experienced with React. I am having errors while refreshing my page. I think this is my issue: When I am refreshing my page, I think the getInitialProps function is triggering, but for some reason it doesn't appear that it is starting from the beginning. I have an await fetch to get some data, which is being stored in a variable reviewOffice. I am then trying to use reviewOffice.id as an argument for a separate fetch. This is where I'm getting my first error because reviewOffice is considered null. If I try to put a debugger anywhere in the getInitialProps function It is never triggered, in addition If I put any console.log() statements I will not see it, however it will always fail on the second line of the function "let users = await..."

Why doesn't the page await for the first call like I think it should?

//index.js
const PagesAdminReviewOffice = ({ initialState }) => {
  initialState = initialize(initialState);

  return (
    <RouteProtect>
      <AdminReviewOfficeMenu>
        <AdministrationStateProvider initialAdministrationState={initialState}>
          <AdminUserConfigProvider>
            <PopWidth>
              <Stack gapSize="32">
                <ReviewOffice></ReviewOffice>
              </Stack>
            </PopWidth>
          </AdminUserConfigProvider>
        </AdministrationStateProvider>
      </AdminReviewOfficeMenu>
    </RouteProtect>
  );
};

PagesAdminReviewOffice.getInitialProps = async ({ req }) => {
  let reviewOffice = await getReviewOffice();
  let users = await getUsers(reviewOffice.id);

  let primaryId = await fetchWrapper({
    url: `${HOST}/api/ReviewOffice/Contacts/PrimaryId`,
    req,
  })
  
  var initialState = await getInitialReviewOfficeState(
    getReviewOffice,
    updateReviewOffice,
    getUsers,
    getContacts,
    createAdminUser,
    deleteAdminUser,
    updateContact,
    createContact,
    deleteContact,
    setPrimaryContact,
    getApprovalTypeContacts,
    createApprovalTypeContact,
    updateApprovalTypeContact,
    deleteApprovalTypeContact,
    getApprovalTypes,
    getTags,
    createTag,
    updateTag,
    deleteTag,
    reviewOffice,
    users,
    primaryId
  );

  return {
    initialState: initialState,
  };
};
export default PagesAdminReviewOffice;

Here are the functions getReviewOffice() and getUsers(), I forgot to add them in op

// reviewOfficeFunctions.js
export const getReviewOffice = (req) => {
  return fetchWrapper({
    url: `${HOST}/api/ReviewOffice`,
    req,
  })
};

export const getUsers = (id, req) => {
  return fetchWrapper({
    url: `${HOST}/api/AdminUser/ReviewOffice/${id}`,
    req,
  });
};

And here is my fetchWrapper:

const { OAUTH_COOKIE_PREFIX } = get();

const fetchWrapper = async (
  { url, fetchOptions, req },
  returnResponse = false
) => {
  const tokens = grabTokensFromCookies(req, OAUTH_COOKIE_PREFIX);
  let response;
  let json = {};
  try {
    response = await fetchWithTokens({
      ...tokens,
      cookiePrefix: OAUTH_COOKIE_PREFIX,
      url,
      fetchOptions: {
        redirect: "error",
        credentials: "omit",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json",
        },
        ...fetchOptions,
      },
    });

    if (returnResponse) {
      return response;
    }

    const { status } = response;
    if (response.ok) {
      if (response.headers.get("content-length") !== "0") {
        json = response.json();
      }
    } else if ((status === 400 || status === 401) && isBrowser) {
      // 400 Bad Request = invalid refresh token, and various other issues
      // 401 Unauthorized = invalid access token
      // Node tries to refresh the access token, so if we get one of the
      //   above errors it means we need to log in again.
      // Reload allows us to maintain our current page but unfortunately
      //   not state because user will be redirected to the login page.
      //   Consider other ways to respond if this does not meet your needs.
      location.reload();
    } else {
      throw `Response not OK, status: ${status}`;
    }
  } catch (err) {
    // 403 Forbidden = not authorized
    // Other errors that can not be handled by attempting to re-authenticate.
    // TODO in your project, handle the error - forward to an error page?
    console.error(err); // eslint-disable-line no-console
    throw err;
  }

  return returnResponse ? response : json;
};

export default fetchWrapper;


Solution 1:[1]

I think the issue lies in your fetchWrapper utility. After looking over the code, the returnResponse value is false by default, which means the function attempts to return the JSON data but doesn't appear to wait for the response.json(); Promise to resolve. Because of this, the initial json value of {} is returned and reviewOffice.id is undefined.

const fetchWrapper = async (
  { url, fetchOptions, req },
  returnResponse = false
) => {
  const tokens = grabTokensFromCookies(req, OAUTH_COOKIE_PREFIX);
  let response;
  let json = {};
  try {
    response = await fetchWithTokens({ ..... });

    if (returnResponse) {
      return response;
    }

    const { status } = response;
    if (response.ok) {
      if (response.headers.get("content-length") !== "0") {
        json = await response.json(); // <-- await Promise to resolve
      }
    } else if ((status === 400 || status === 401) && isBrowser) {
      // ...
      location.reload();
    } else {
      throw `Response not OK, status: ${status}`;
    }
  } catch (err) {
    ...
  }

  return returnResponse ? response : json;
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Drew Reese