DEV Community

Cover image for Fetching Data With Next.js - part 6
Lorenzo Zarantonello for This is Learning

Posted on

Fetching Data With Next.js - part 6

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.

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 to get data from jsonplacceholder.

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();
}


Enter fullscreen mode Exit fullscreen mode

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'


Enter fullscreen mode Exit fullscreen mode

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 }) { ... }


Enter fullscreen mode Exit fullscreen mode

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.

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 }) { ... }


Enter fullscreen mode Exit fullscreen mode

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>


Enter fullscreen mode Exit fullscreen mode

The line below



  {users && users.map(({ id, name, website }) => (


Enter fullscreen mode Exit fullscreen mode

uses the logical AND (&&) operator to run the map method on users only if users is truthy.

You might get something like this:

Visualize Data On Next.js

Other JavaScript operators you may want to know:

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.

Top comments (9)

Collapse
 
mezieb profile image
Okoro chimezie bright

Yeaaaaa great you made it thanks for your input💪💪💪💪

Collapse
 
lorenzojkrl profile image
Lorenzo Zarantonello

I’m thinking of making another post for this series with a new app including what I learned + deployment. Maybe I’ll have time next week:)
Are you working on a personal project?

Collapse
 
mezieb profile image
Okoro chimezie bright

Yes with Next.js but the project will include login,signup,dashboard with user profile,search option,list display,single detail page,payment method,api and database yes something like that in a components bases someone can use in a real world application.thanks you covered api👍,i'm following you

Collapse
 
peeyar profile image
Rajesh

Thanks a lot. You are a good teacher.

Collapse
 
khairunnisaas profile image
Khairunnisaas

your articles is so great! i love you split you journey articles into small chunk. im also new with next js, and i tried to create a simple CRUD budget app that would track your income / expense with next js, but i have a problem with the fetching data.

so when i tried to add new income / expense data, the new data added is not automatically updated to the display, i need to refresh the page first to get the new data. i used getServerSideProps to fetch data from the api. by using getServerSideProps it should be automatically fetch the data right? or am i missing something?

Collapse
 
lorenzojkrl profile image
Lorenzo Zarantonello

Hey thanks!

It’s hard to help without seeing the code. But it sounds like you 1) request initial data when you visit the page 2) update data on server 3) expect the updates to reflect in your app. However 3) doesn’t happen because the backend doesn’t “push” the changes to the frontend.
You might set up your API to support POST requests that return updated data

Collapse
 
cyberraff profile image
cyberraff

Thanks for this piece of information.

Collapse
 
cikadraza profile image
Milan Drazic

I do the same like this but have problem. Rendering page is too slow. I used shallow routing and it ISC help.
But I want without it?

Collapse
 
lorenzojkrl profile image
Lorenzo Zarantonello

Could you share some code?