Fetching Data With Next.js - part 6
Tags: nextjs, react, tutorial, javascript
Published: 2023-03-30 05:08:32

In the previous post, we saw how to read and write data from and into a local JSON file in an Next.js app.

You don't need to read that to go through this post.

Now, we take a step further and fetch data from a server through a REST API. The same works for getting data from the file system (if you don't use routes), or databases.

## Fetching Data & Pre-rendering

Fetching data from an exernal source brings us back to the concept of [pre-rendering](https://dev.to/this-is-learning/reading-local-json-data-with-nextjs-part-5-59le).

In short, Next.js creates the HTML for each page in advance to improve performances.

You can build on pre-rendering in two ways:
- using `getStaticProps()` if the content to get from the external API doesn't change frequently. The `getStaticProps()` function is used to fetch data at build time.
- using `getServerSideProps()` when the content changes more frequently. The `getServerSideProps()` function fetches data on every request, and is used for dynamic pages that need to be updated frequently.

## Using Static Generation To Fetch Data From A Server

Inside the lib folder we create a new file and we call it users.js. 

In this file, we will store the logic to fetch data from Jsonplaceholder.

The following code creates an asynchronous function called `getUsers()`. It uses the [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to get data from [jsonplacceholder](https://jsonplaceholder.typicode.com/users). 

If the Promise completes successfully, it returns data in a JSON format.

```
export async function getUsers() {
  // Fetch data from an external API endpoint
  const res = await 
  fetch('https://jsonplaceholder.typicode.com/users')
  if (!res.ok) throw new Error('failed to fetch data')
  return res.json();
}
```

### Fetch Data With getStaticProps()
Now, inside index.js we can take advantage of the async `getStaticProps()` function to call `getUsers()`.

First, we need to import `getUsers()` in index.js as follows:

```
  ...
  import { getUsers } from '../lib/users'
```

Then, we need to declare the async `getStaticProps()` function outside the Home component. Here you can see the structure of the Home component in index.js at this point.

```
  ...
  import { getUsers } from '../lib/users'

  export async function getStaticProps() { ...  }

  export default function Home({ localData }) { ... }
```

In the body of `getStaticProps()` we can add the code to trigger `getUsers()`. 

Don't worry about localData, that is a piece of code from the previous article where we got [data from a local JSON file](https://dev.to/this-is-learning/reading-local-json-data-with-nextjs-part-5-59le).

We assign the data from `getUsers()` to the users variable and we return it as a property.

Notice that we pass the property to the Home component as well.


```
  ...
  import { getUsers } from '../lib/users'

  export async function getStaticProps() { 
    const users = await getUsers()
    const localData = await getLocalData()

    console.log(users);
    return {
      props: {
        localData,
        users
      },
    };
  }

  export default function Home({ users, localData }) { ... }
```

Finally, notice the `console.log(users);`. 
You will not see the log in your browser's console because it runs on the server-side and not on the client-side.

Therefore, you will see the log in the terminal you use to run your Next.js application.

By adding some JSX code inside the Home component you can get the list of users on screen (CSS omitted for clarity).

```
<section>
  <h2>Users</h2>
  <ul>
    {users && users.map(({ id, name, website }) => (
      <li key={id}>
        {id} - {name}
         <br />
        {website}
      </li>
     ))}
  </ul>
</section>
```
The line below
```
  {users && users.map(({ id, name, website }) => (
```
uses the [logical AND (&&) operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND) to run the map method on `users` only if `users` is truthy.

You might get something like this:

![Visualize Data On Next.js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hfj0wce5xd0z4w14wxdm.png)

Other JavaScript operators you may want to know:
- [The JavaScript ?? (Nullish Coalescing) Operator](https://javascript.plainenglish.io/javascript-operator-5d3bd92e835e)
- [Ternary Operator](https://javascript.plainenglish.io/javascript-ternary-operator-b76a02c90850)
- [Optional Chaining](https://javascript.plainenglish.io/javascript-optional-chaining-7a2bce30c450)

### Fetch Data With getStaticProps()

The `getServerSideProps` function is used to fetch data on every request, and is used for dynamic pages that need to be updated frequently. 

In this example we can simply swap 'getStaticProps' for `getServerSideProps` and the code will run just fine.

However, rememebr that
- `getStaticProps()` fetches data at build time and it is a good choice if the content to get from the external API doesn't change frequently. 
- `getServerSideProps()` fetches data on every request, and is used for dynamic pages that need to be updated frequently.