# Lost on data fetching in a server component

**URL:** <https://forum.codewithmosh.com/t/lost-on-data-fetching-in-a-server-component/24363>\
**Category:** Next.js\
**Created:** [January 1, 2024, 5:53am UTC](https://forum.codewithmosh.com/t/lost-on-data-fetching-in-a-server-component/24363 "2024-01-01T05:53:47Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![sawfiz1](https://avatars.discourse-cdn.com/v4/letter/s/b77776/32.png) [@sawfiz1](https://forum.codewithmosh.com/u/sawfiz1)\
**Post date:** [January 1, 2024, 5:53am UTC](https://forum.codewithmosh.com/t/lost-on-data-fetching-in-a-server-component/24363/1 "2024-01-01T05:53:47Z")

</div>

Hi, all,

Happy 2024!

I am asking for help as I am lost on how to fetch data on the server side.

Referring to the `LastestIssue` component, I know directly getting data using prisma works. But I do not like it because:

- it skips the api
- no error handling

I tried to implement my own data fetching using `fetch` and `axios`, but was unsuccessful.

```tsx
import axios from "axios";

const LatestIssues = async () => {
  // Fetch data using axios
  // Make sure 
  // - use the full url
  // - no `/` at the end of the url
  const response = await axios.get("http://localhost:3000/api/issues")
  const issues = response.data;

  return (
    <>
      <div>Latest Issues</div>
      <ul>
        {issues.map((issue) => (
          <li key={issue.id}>{issue.title}</li>
        ))}
      </ul> 
    </>
  );
};

export default LatestIssues;

```

While data is fetched, it can not be rendered because of the async nature of data fetching. `issues` are not available for rendering.

We usually solve this on the client side using `useEffect` and `useState` to set up a `loading` state. But this is not possible unless I change this component into a client side component.

I also looked into using `getServerSideProps()`, but it works only with files in `/pages’, and I think with this tutorial we are moving away from the old page routing.

So, is there a way to keep this as a server component and fetch data from API using `fetch` / `axios`?

Many thanks, and happy learning!

Sawfiz

---

<div class="post-metadata">

**Author:** ![sawfiz1](https://avatars.discourse-cdn.com/v4/letter/s/b77776/32.png) [@sawfiz1](https://forum.codewithmosh.com/u/sawfiz1)\
**Post date:** [January 1, 2024, 11:19am UTC](https://forum.codewithmosh.com/t/lost-on-data-fetching-in-a-server-component/24363/2 "2024-01-01T11:19:26Z")

</div>

Hi, all,

After some research, I have come to some clarity.

## Next.js app router vs. page router

With the introduction of the new Next.js app router, many things are simplified.

- no more use of `@/app/pages`
- special files, e.g, pages. tsx, error.tsx, loading.tsx, etc.
- much simpler data fetching  
– components can be `async’  
– directly fetch data using prisma, axios, fetch

## Recommendation from Next.js

> **[Getting Started: Fetching Data | Next.js](https://nextjs.org/docs/app/getting-started/fetching-data)**
>
> Learn how to fetch data and stream content that depends on data.

Whenever possible, we recommend fetching data on the server with Server Components. This allows you to:

- Have direct access to backend data resources (e.g. databases).
- Keep your application more secure by preventing sensitive information, such as access tokens and API keys, from being exposed to the client.
- Fetch data and render in the same environment. This reduces both the back-and-forth communication between client and server, as well as the [work on the main thread](https://vercel.com/blog/how-react-18-improves-application-performance) on the client.
- Perform multiple data fetches with single round-trip instead of multiple individual requests on the client.

My understanding is, it is recommended to fetch data using prisma.

I list below 3 ways to fetch data in the case of `LatestIssues`

### Fetching using Prisma

> [!success] Pro
> 
> - This is the simplest way when the backend had direct access to the database.
> - It is also the recommended way as without going through the API, it is faster and more secure.
> - Also, there is no need to explicitly define the type of `issues`

> [!failure] Con
> 
> - Only works when the backend had direct access to the database.

```tsx
import prisma from "@/prisma/client";

const LatestIssues = async () => {
  // Fetch using Prisma
  const issues = await prisma.issue.findMany({
    orderBy: { createdAt: "desc" },
    take: 5,
  });

  return (
    <>
      <div>Latest Issues</div>
      <ul>
        {issues.map((issue) => (
          <li key={issue.id}>{issue.title}</li>
        ))}
      </ul>
    </>
  );
};

```

Note:  
The data fetching can not be put into a `try...catch` block, doing so will make `issues` inaccessible in `return`

### Fetching using axios

> [!success] Pro
> 
> - Works with external APIs

> [!failure] Con
> 
> - Need to add explicit type definition of `issues`
> - Complex URL, easy to make mistakes

```tsx
import axios from "axios";

const LatestIssues = async () => {
  // Fetch data using axios
  // Make sure 
  // - use the full url
  // - no `/` at the end of the url
  const response = await axios.get(
    "http://localhost:3000/api/issues?orderBy=updatedAt&sort=desc&page=1&pageSize=5"
  );
  const issues: Issue[] = response.data.issues;

  return (
    <>
      <div>Latest Issues</div>
      {/* <ul>
        {issues.map((issue) => (
          <li key={issue.id}>{issue.title}</li>
        ))}
      </ul> */}
    </>
  );
};

export default LatestIssues;

```

### Fetch using `fetch`

> [!success] Pro
> 
> - Works with external APIs

> [!failure] Con
> 
> - Need to parse json and deconstruct `res`
> - Type definition of `issues` is more complex
> - Complex URL, easy to make mistakes

```tsx
import {Issue} from '@prisma/client'

const LatestIssues = async () => {
  // Fetch data using fetch
  // Make sure 
  // - use the full url
  // - no `/` at the end of the url
  const res = await fetch(
    "http://localhost:3000/api/issues?orderBy=updatedAt&sort=desc&page=1&pageSize=5"
  );
  // Deconstruct issues.issues
  const { issues }: { issues: Issue[] } = await res.json();

  return (
    <>
      <div>Latest Issues</div>
      <ul>
        {issues.map((issue) => (
          <li key={issue.id}>{issue.title}</li>
        ))}
      </ul>
    </>
  );
};

export default LatestIssues;

```

## Outstanding issues

1. For some reason, I can not use `orderBy=createdAt` in the urls used in axios and fetch. Other fields, e.g., status and updatedAt work…
2. I need to figure out how to add error handling in each of the above 3 ways.

Thanks,  
Sawfiz

---

<div class="post-metadata">

**Author:** ![infohills](https://avatars.discourse-cdn.com/v4/letter/i/96bed5/32.png) [@infohills](https://forum.codewithmosh.com/u/infohills)\
**Post date:** [March 21, 2024, 11:45pm UTC](https://forum.codewithmosh.com/t/lost-on-data-fetching-in-a-server-component/24363/3 "2024-03-21T23:45:30Z")

</div>

It seems like you’re trying to fetch data from an API within a server-side component in your Next.js application. Since server-side rendering doesn’t support asynchronous operations directly within the component, you need to handle data fetching differently. One way to achieve this is by using `getServerSideProps` in Next.js.

Here’s how you can refactor your component to use `getServerSideProps`:  
import axios from “axios”;

const LatestIssues = ({ issues }) =\> {  
return (  
\<\>

Latest Issues
  

  
{issues.map((issue) =\> (  
- {issue.title}
  
))}  

  
\</\>  
);  
};

export async function getServerSideProps() {  
try {  
const response = await axios.get(“[http://localhost:3000/api/issues](http://localhost:3000/api/issues)”);  
const issues = response.data;  
return {  
props: { issues },  
};  
} catch (error) {  
console.error(“Error fetching data:”, error);  
return {  
props: { issues: }, // Return empty array if there’s an error  
};  
}  
}

export default LatestIssues;
