0

apparently, it is considered a best practice if you can split all the data fetching functions to a separate folder called services and put all the functions there then use them in the project However, I couldn't make it happen with Next.js The function works when I put it inside the same component I want to render the data inside it, but doesn't work when I put the function in a separate folder and export it. I get this error:

 TypeError: Cannot read properties of undefined (reading 'map')

I think it is because the data props are not being passed to the component correctly.

below are the working and none working examples :

the Working example:

inside index.tsx file :

export async function getStaticProps() {
  const response = await fetch(
    `https://api.github.com/users/abdurrahmanseyidoglu/repos`
  );
  const data = await response.json();

  if (!data) {
    return {
      notFound: true,
    };
  }

  return {
    props: {
      data,
    }, // will be passed to the page component as props
  };
}

const Home = ({ data }) => {
  return (
    <>
      <ul>
        {data.map((repo) => (
          <li key={repo.id}>{repo.name}</li>
        ))}
      </ul>
      <p className="max-w-5xl m-auto text-justify mt-2 border rounded p-3 shadow-lg">
       Working Example
      </p>
    </>
  );
};

export default Home;

Not Working example:

inside services/getUserRepos.ts :

export async function getStaticProps() {
  const response = await fetch(
    `https://api.github.com/users/abdurrahmanseyidoglu/repos`
  );
  const data = await response.json();

  if (!data) {
    return {
      notFound: true,
    };
  }

  return {
    props: {
      data,
    }, 
  };
}

inside index.tsx file :

import { getStaticProps } from "../services/getUserRepos";
const Home = ({ data }) => {
  return (
    <>
      <ul>
        {data.map((repo) => (
          <li key={repo.id}>{repo.name}</li>
        ))}
      </ul>
      <p className="max-w-5xl m-auto text-justify mt-2 border rounded p-3 shadow-lg">
       None Working Example
      </p>
    </>
  );
};

export default Home;

How can I make it so I can pass the fetched data from a separate folder to my index.tsx file

4
  • getStaticProps need to be exported from the page file. You import it and don't do anything with it. So index.tsx has no exported function getStaticProps and therefore doesn't work. nextjs.org/docs/basic-features/data-fetching/get-static-props Commented Jul 14, 2022 at 12:19
  • You can declare the inner logic of the getStaticProps function into a separate function/file, for reusability. Import the function and use is within the getStaticProps function, which you then export. Commented Jul 14, 2022 at 12:20
  • @W.S. I'm getting this error Error: Error serializing `.data` returned from `getStaticProps` in "/". Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value. Commented Jul 14, 2022 at 12:33
  • @W.S. if you can provide a working solution I would appreciate it. Commented Jul 14, 2022 at 12:37

2 Answers 2

1

inside services/user.service.ts :

export async function getUserRepos() {
  const response = await fetch(
    `https://api.github.com/users/abdurrahmanseyidoglu/repos`
  );
  const data = await response.json();
  return data;
}

inside index.tsx file :

import { getUserRepos } from "../services/user.service";

export async function getStaticProps() {
  const data = await getUserRepos();

  if (!data) {
    return {
      notFound: true,
    };
  }

  return {
    props: {
      data,
    }, // will be passed to the page component as props
  };
}

const Home = ({ data }) => {
  return (
    <>
      <ul>
        {data.map((repo) => (
          <li key={repo.id}>{repo.name}</li>
        ))}
      </ul>
      <p className="max-w-5xl m-auto text-justify mt-2 border rounded p-3 shadow-lg">
       Working Example
      </p>
    </>
  );
};

export default Home;
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you!, now I understand how to use a function from another file/folder with SSG support
1

You are not using getStaticProps after importing it, your code should look like this

import {getStaticProps} from "../services/getUserRepos";
import {useState} from "react";

const Home = () => {
    const [userRepos, setUserRepos] = useState([]);

    getStaticProps().then((data) => setUserRepos(data));

    return (
        <>
            <ul>
                {userRepos.map((repo) => (
                    <li key={repo.id}>{repo.name}</li>
                ))}
            </ul>
            <p className="max-w-5xl m-auto text-justify mt-2 border rounded p-3 shadow-lg">
                None Working Example
            </p>
        </>
    );
};

export default Home;

5 Comments

I'm getting this error : Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.
if you can provide a fully working solution I would appreciate it.
@MrXQ Yep, my bad i didn't catch that fully, i've edited the message and fixed it.
Thank you, It is working now, Do you know How can I achieve it using thegetStaticProps function for SSG? Like what W.S said in his comment
Im not too sure about that, but i believe that when u build the production it will automatically put static pages in the build folder. But again i've never tried it so im not sure on how it works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.