How to fetch API data from Axios inside the getServerSideProps function in NextJS?

14,162

Solution 1

Do not use Axios. Just use fetch().

Next.js polyfills fetch() by default on both the client and server, so you can just use it:

In addition to fetch() on the client-side, Next.js polyfills fetch() in the Node.js environment. You can use fetch() in your server code (such as getStaticProps/getServerSideProps) without using polyfills such as isomorphic-unfetch or node-fetch.

Source.

Solution 2

Your problem is that your async method does not return a promise.

import service from '../service'

export const getAllAccounts = async (adminToken) => {
  const res = service({ jwtToken : adminToken }).get(`/accounts`);
  return res;
}
Share:
14,162
Admin
Author by

Admin

Updated on July 13, 2022

Comments

  • Admin
    Admin almost 2 years

    I'm building an App with Next.js, and I need to connect to specific API routes (set up with API Platform) and populate pages with the route's responses.

    The API is working fine, but no matter how I try to implement my Axios call inside the getServerSideProps, I always get the same error, ECONNREFUSED, from my Node stack.

    I tried to get the data from useEffect() and it's working fine, but I would like to know if there's a way to call it directly in getServerSideProps.

    I'm using a Node container for Docker, and the routes are authenticated through a JWT Token (stored in the session and the client cookies for the server-side connection)

    Here are is my code:

    pages/accounts.js:

    export async function getServerSideProps(context) {
      const cookies = new Cookies(context.req.headers.cookie)
      const adminToken = cookies.get('jwtToken')
    
      const res = await getAllAccounts(adminToken)
    
      return {
        props: {
          testdata: ''
        },
      }
    }
    

    lib/accounts.js:

    import service from '../service'
    
    export const getAllAccounts = async (adminToken) => {
      const res = service({ jwtToken : adminToken }).get(`/accounts`).then((response) => {
      
      }).catch((error) => {
        console.dir(error)
      })
    }
    

    HTTP wrapper:

    import axios from 'axios';
    import jwt_decode from "jwt-decode";
    import mockAdapter from 'axios-mock-adapter';
    
    const service = ({ jwtToken = null, store = null, mockURL = null, mockResponse = null, multipart = false } = {}) => {
      const options = {};
    
      options.baseURL = process.env.NEXT_PUBLIC_API_URL + '/api';
    
      if(multipart === true) {
        options.headers = {
          'Content-Type': 'multipart/form-data'
        }
      } else {
        options.headers = {
          'Content-Type': 'application/ld+json',
          accept: 'application/ld+json'
        }
      }
    
      const instance = axios.create(options);
    
      instance.interceptors.response.use(response => {
        return response;
      }, error => {
        return Promise.reject(error);
      })
    
      if (mockURL !== null && mockResponse !== null) {
        let mock = new mockAdapter(instance);
        mock.onAny(mockURL).reply(200, mockResponse)
      }
    
      return instance;
    };
    
    export default service;
    

    Through the error dump in the node stack, I managed to see that the request headers are correct, and the JWT correctly passed through.