Tips for leveraging the functions service in Next.js for better code reusability

I am just starting to learn Next.js and I have a preference for organizing my API functions in a separate folder called services. I attempted to implement some code based on this topic but unfortunately, it did not work as expected. It seems like my api function is not being called, leading to the following error:

Unhandled Runtime Error
TypeError: data is undefined

Here is a snippet of my code:

index.tsx file :

import ShowResult from '../components/showResult'

export default function Home() {
  return (
    <div className='container mx-auto'>      
      <ShowResult />
    </div>
  );
}

components/showResult.tsx file :

import getUserRepos from '../services/api.service'

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

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

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

export default function ShowResult({data}) {
  return (
    <div className=''>
      <p>Result :</p>
      <ul>
        {data.map((repo) => (
          <li key={repo.id}>{repo.name}</li>
        ))}
      </ul>
    </div>
  )
}

services/api.service.ts file :

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

Any advice on how to properly retrieve data from my api service function would be greatly appreciated.

Answer №1

To start, make sure you relocate getStaticProps to your page and then pass the fetched data to the ShowResult component as a prop. Next, update your ShowResult component to receive the data as a prop and display it.

You can follow these steps:

pages/index.tsx:

import ShowResult from '../components/ShowResult';
import { getUserRepos } from '../services/api.service';

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

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

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

export default function Home({ data }) {
  return (
    <div className='container mx-auto'>      
      <ShowResult data={data} />
    </div>
  );
}

components/ShowResult.tsx:

export default function ShowResult({ data }) {
  if (!data) {
    return <div>No data to display.</div>;
  }

  return (
    <div className=''>
      <p>Result:</p>
      <ul>
        {data.map((repo) => (
          <li key={repo.id}>{repo.name}</li>
        ))}
      </ul>
    </div>
  );
}

services/api.service.ts (unchanged):

export async function getUserRepos() {
  const response = await fetch(
    `https://api.github.com/users/abdurrahmanseyidoglu/repos`
  );
  if (!response.ok) {
    throw new Error(`Failed to fetch repos, received status ${response.status}`);
  }
  const data = await response.json();
  return data;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there any way I can verify the invocation of signOut in this Jest test case?

I am attempting to perform testing on my home page within a next app. However, I have encountered an issue with a button in the Home component that triggers a logout firebase function. Despite my attempts to mock this function and verify whether or not i ...

What are the steps for setting up PancakeSwap V2 on a testnet environment?

I am currently testing the Pancakeswap v2 frontend repository on my local host, but I am encountering an issue when trying to switch to the testnet. (https://github.com/pancakeswap/pancake-frontend) I receive an error message when I change the value of NEX ...

Is it possible to create a tuple with additional properties without needing to cast it to any type?

To accommodate both array and object destructuring, I have defined the following `Result` type: type Errors = Record<string, string | null>; type Result = [Errors, boolean] & { errors: Errors; success: boolean }; I attempted to create a result of t ...

The getSession provided by the getSession function is accessible within getServerSideProps but appears as undefined within the component

Whenever I try to log the session variable inside the Dashboard component, it comes back as undefined. However, when I log it inside the getServerSideProps function, it returns the correct details. Am I missing something here? Objective: My goal is to fet ...

Encountering a Typescript issue with mongoose

Working with node.js and various email addresses, I encountered a compile error: TS2345: Argument of type '(error: any, document: any) => void' is not assignable to parameter of type '(err: any) => void'. This error occurs at the l ...

Ensuring the Presence of a Legitimate Instance in NestJS

I have been working on validating my request with the Product entity DTO. Everything seems to be in order, except for the 'From' and 'To' fields. The validation works correctly for the Customer and Type fields, but when incorrect data i ...

Is it possible to modify the number format of an input field while in Antd's table-row-edit mode?

I am currently utilizing the Table Component of Ant Design v2.x and unfortunately, I cannot conduct an upgrade. My concern lies with the inconsistent formatting of numbers in row-edit mode. In Display mode, I have German formatting (which is desired), but ...

Encountered Error: Rendered an excessive number of hooks beyond the previous render in the framework of Typescript and

I am currently working on integrating Typescript and Context API in an application. Specifically, I am focusing on setting up the Context API for handling login functionality. However, I encountered the following error message: Error: Rendered more hooks ...

"Unleashing the power of custom servers to tap into the rendered HTML of Next

In my quest to serve a server-side generated page as a file using next.js, I decided to extract the rendered content within a custom server.js file: const express = require('express'); const next = require('next'); const port = parseIn ...

Tips for eliminating unicode characters from Graphql error messages

In my resolver, I have implemented a try and catch block where the catch section is as follows: catch (err: any) { LOG.error("Failed to get location with ID: " + args.id); LOG.error(err); throw new Error(err); ...

Ways to recycle functional elements in Next.js 13 Server Components

Encountering a problem trying to separate the logic from the component due to this error message: Error: Event handlers cannot be passed to Client Component props. <textarea rows={18} placeholder=... onInput={function}> ...

Encountering an issue while trying to deploy my node.js application on Heroku

While monitoring the Heroku logs using the command heroku --tail, I encountered the following error: Error: 2022-01-25T19:10:06.153750+00:00 app[web.1]: at emitErrorCloseNT (node:internal/streams/destroy:122:3) 2022-01-25T19:10:06.157055+00:00 heroku[rout ...

How can a TypeScript object be declared with a single value assignment to itself?

Whenever I try to declare an object and assign a key to itself, I encounter errors. I have attempted different methods, but the error persists. const a = { d:123, a:a//<-TS2448: Block-scoped variable 'a' used before its declaration. } co ...

Guide to asynchronously loading images with Bearer Authorization in Angular 2 using NPM

I am in search of a recent solution that utilizes Angular2 for my image list. In the template, I have the following: <div *ngFor="let myImg of myImages"> <img src="{{myImg}}" /> </div> The images are stored as an array w ...

Text that doesn't appear overwhelming in a Framer Motion text reveal animation

As a newcomer to Framer Motion, I recently attempted to create a Stagger Text effect and a Text Reveal Animation for my portfolio based on various articles. However, despite trying multiple examples, I have encountered an issue where the animation occurs s ...

What is the significance of `new?()` in TypeScript?

Here is a snippet of code I'm working with in the TypeScript playground: interface IFoo { new?(): string; } class Foo implements IFoo { new() { return 'sss'; } } I noticed that I have to include "?" in the interface met ...

Choosing multiple lists in Angular 2 can be achieved through a simple process

I am looking to create a functionality where, upon clicking on multiple lists, the color changes from grey to pink. Clicking again will revert the color back to grey. How can I achieve this using class binding? Below is the code snippet I have tried with ...

Step-by-step guide for adding an object to a Material UI select component

I am in the process of incorporating a Select component with reactjs material ui and typescript. Yet, I encounter this typing error: Property 'id' does not exist on type 'string'. Property 'name' does not exist on type ' ...

Typescript - Troubleshooting undefined error with static variables

My node API app is developed using express and typescript. The static variable of the Configuration Class is initialized with required configuration before starting the server. However, when I try to use this static variable in a separate TypeScript class ...

What is the best way for a function to accommodate various types that adhere to an interface?

How can we create a function that can accept multiple types with a common interface? Let's consider the example: interface A {a: number} type B = {b: string;} & A type C = {c: string;} & A function acceptA(a: A) { return a } acceptA({a ...