1

I've this code into pages folder on my NextJS environment. It gets data calling an external API Rest, and it's working because the console.log(response); line show me by console the Json API response. The problem I've is that I get this error in browser:

TypeError: Cannot read property 'json' of undefined

Corresponding with this line code:

const data = await res.json();

This is the complete file with the code:

import React from "react";
import fetch from "node-fetch";

const getFetch = async (invoicesUrl, params) => {
  fetch(invoicesUrl, params)
    .then((response) => {
      return response.json();
    })
    .then((response) => {
      console.log(response);
    })
    .catch((err) => {
      console.log(err);
    });
};

export const getServerSideProps = async () => {
  const invoicesUrl = "https://192.168.1.38/accounts/123456";
  const params = {
    method: "get",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
    },
  };
  const res = await getFetch(invoicesUrl, params);
  const data = await res.json();
  console.log("Data Json: ", data);

  return { props: { data } };
};

This is the Json API response that I see by console:

{
  account: [
    {
      id: '7051321',
      type: 'probe',
      status: 'open',
      newAccount: [Object],
      lastDate: '2020-07-04',
      taxExcluded: [Object],
      totalRecover: [Object],
      documentLinks: []
    },
  ]
}

Any idea how can I solve it? Thanks in advance.

UPDATE Here the code working good:

import React from "react";
import fetch from "node-fetch";

const getFetch = async (invoicesUrl, params) => {
   return fetch(invoicesUrl, params);
};

export const getServerSideProps = async () => {
  const invoicesUrl = "https://192.168.1.38/accounts/123456";
  const params = {
    method: "get",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
    },
  };
  try {
    const res = await getFetch(invoicesUrl, params);
    const data = await res.json();
    console.log("Data JSON: ", data);
    return { props: { data } };
  } catch (error) {
    console.log("Data ERROR: ", error);
  }
};

Sebastian Diaz
  • 155
  • 7
  • 19

2 Answers2

1

There are a couple of things you have to change.

const getFetch = async (invoicesUrl, params) => {
  fetch(invoicesUrl, params)
    .then((response) => {
      return response.json();
    })
    .then((response) => {
      console.log(response);
      return response; // 1. Add this line. You need to return the response.
    })
    .catch((err) => {
      console.log(err);
    });
};

export const getServerSideProps = async () => {
  const invoicesUrl = "https://192.168.1.38/accounts/123456";
  const params = {
    method: "get",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
    },
  };
  const data = await getFetch(invoicesUrl, params);
  // const data = await res.json(); 2. Remove this you have already converted to JSON by calling .json in getFetch
  console.log("Data Json: ", data); // Make sure this prints the data.

  return { props: { data } };
};

sidthesloth
  • 1,399
  • 1
  • 11
  • 19
  • I've made that changes you suggest, and now I get this error: "SerializableError: Error serializing `.data` returned from `getServerSideProps` in "/invoicing/invoices". Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value all together". There are two "return" into your getFetch function, is that correct? – Sebastian Diaz Sep 09 '20 at 18:39
  • The reason is that the response returned from your API is not serializable. If you update your question with the full object I will be able to point where the problem is. If not, you can find it out yourself using the answer here: https://stackoverflow.com/questions/30579940/reliable-way-to-check-if-objects-is-serializable-in-javascript – sidthesloth Sep 09 '20 at 18:48
  • Ok, probably the reason to not be serializable is those elements with content "[Object]" in the console but with content if I call the API with another way (curl, Postman). – Sebastian Diaz Sep 09 '20 at 19:10
  • Yes, it is something inside [Object] that is not serializable. For NextJS, it needs to be serializable. You can use this: https://stackoverflow.com/questions/41587443/trying-to-print-the-nested-json to print the entire structure and see where the problem is. I'll be happy to help more. Btw I think I have fixed the original issue for the question. If so please accept..:) – sidthesloth Sep 09 '20 at 19:16
  • Thanks for the help. I'll take a look to that link. Sorry, but I can't accept your answer as correct (i don't want confuse another users) because it can't work for me after try many times. I've updated my original question and after UPDATE title I putted the code that works for me. However, may be another user with this issue can vote your answer as the right! Thanks again. – Sebastian Diaz Sep 09 '20 at 19:42
  • No problem.. :) – sidthesloth Sep 09 '20 at 19:44
1

You have return statement in wrong place. When the function is expecting a return. You need to return when the statements are executed not inside the promise then function because it is an async callback function which is not sync with the statement inside getFetchfunction. I hope i have made things clear. Below is the code which will any how return something

import React from "react";
import fetch from "node-fetch";

const getFetch = async (invoicesUrl, params) => {
  return fetch(invoicesUrl, params);
};

export const getServerSideProps = async () => {
  const invoicesUrl = "https://192.168.1.38/accounts/123456";
  const params = {
    method: "get",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
    },
  };
  try{
     const res = await getFetch(invoicesUrl, params);
     console.log("Data Json: ", res);
  }catch(error){
     console.log("Data Json: ", error);
  }
  return { props: { res } };
};
Sunil Choudhary
  • 329
  • 1
  • 6
  • Ok, thanks! it helped me. Now my code is working. I will update my original question with the code working. However, here I thing you should change "return { props: { data } }" by "return { props: { res } }". Thanks again. – Sebastian Diaz Sep 09 '20 at 19:12