Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 796
Arnauf Avatar asked Jan 18 '21 15:01

Arnauf


People also ask

Can we use Axios in NextJS?

In this article, I am going to demonstrate how to create a global HTTP request and response handler with Axios Interceptor and used the same in React NextJS application with TypeScript. React and TypeScrip both are very popular nowadays and many developers are using both wisely.

When use getServerSideProps?

You should use getServerSideProps only if you need to render a page whose data must be fetched at request time.

Can I use fetch in NextJS?

Data fetching in Next. js allows you to render your content in different ways, depending on your application's use case. These include pre-rendering with Server-side Rendering or Static Generation, and updating or creating content at runtime with Incremental Static Regeneration.

Can we use getServerSideProps in component?

You cannot use getServerSideProps in non-page components. getServerSideProps can only be exported from a page. You can't export it from non-page files.


3 Answers

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.

like image 126
Aryan Beezadhur Avatar answered Oct 21 '22 20:10

Aryan Beezadhur


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;
}
like image 23
Asen Mitrev Avatar answered Oct 21 '22 20:10

Asen Mitrev


getServerSideProps works well with axios if we return response.data

export const getServerSideProps: GetStaticProps = async ({ params }) => {
  const { brandName } = params as IParams;
  const brandData = await $host.get(`api/brand/${brandName}`).then(response => response.data);

  return {
    props: {
      brand: brandData,
    },
  };
};
like image 23
Maxim Avatar answered Oct 21 '22 18:10

Maxim