- Data Fetching
- async and await in Server Components
- Server Component Functions
- use in Client Components
- Static Data Fetching
- Revalidating Data
- Dynamic Data Fetching
- Data Fetching Patterns
- Parallel Data Fetching
- Sequential Data Fetching
- Blocking Rendering in a Route
- Data Fetching without fetch()
- Default Caching Behavior
- Segment Cache Configuration
- Read JSON DATA and LOAD using JavaScript Async Await
- Table of content
- Starter code
- index.html code
- Create a DB folder and a JSON file within the DB with the following data
- How to validate JSON format
- Add new style-json.css to the project
- Create a JavaScript file to read JSON
- Load JSON data using async await
- Use .then() to load the json data
- Thank you for your time
- Video Tutorial
- Latest Udemy Courses
- Sharing means caring:
Data Fetching
and React Server Components. When using fetch() , requests are automatically deduped by default.
Next.js extends the fetch options object to allow each request to set its own caching and revalidating.
async and await in Server Components
You can use async and await to fetch data in Server Components.
async function getData() const res = await fetch('https://api.example.com/. ') // The return value is *not* serialized // You can return Date, Map, Set, etc. // Recommendation: handle errors if (!res.ok) // This will activate the closest `error.js` Error Boundary throw new Error('Failed to fetch data') > return res.json() > export default async function Page() const data = await getData() return main>main> >
Good to know:
To use an async Server Component with TypeScript, ensure you are using TypeScript 5.1.3 or higher and @types/react 18.2.8 or higher.
Server Component Functions
Next.js provides helpful server functions you may need when fetching data in Server Components:
use in Client Components
use is a new React function that accepts a promise conceptually similar to await . use handles the promise returned by a function in a way that is compatible with components, hooks, and Suspense. Learn more about use in the React RFC
Wrapping fetch in use is currently not recommended in Client Components and may trigger multiple re-renders. For now, if you need to fetch data in a Client Component, we recommend using a third-party library such as SWR
Good to know: We’ll be adding more examples once fetch and use work in Client Components.
Static Data Fetching
By default, fetch will automatically fetch and cache data indefinitely.
fetch('https://. ') // cache: 'force-cache' is the default
Revalidating Data
To revalidate cached data at a timed interval, you can use the next.revalidate option in fetch() to set the cache lifetime of a resource (in seconds).
See Revalidating Data for more information.
Good to know:
Caching at the fetch level with revalidate or cache: ‘force-cache’ stores the data across requests in a shared cache. You should avoid using it for user-specific data (i.e. requests that derive data from cookies() or headers() )
Dynamic Data Fetching
To fetch fresh data on every fetch request, use the cache: ‘no-store’ option.
Data Fetching Patterns
Parallel Data Fetching
To minimize client-server waterfalls, we recommend this pattern to fetch data in parallel:
import Albums from './albums' async function getArtist(username: string) const res = await fetch(`https://api.example.com/artist/$username>`) return res.json() > async function getArtistAlbums(username: string) const res = await fetch(`https://api.example.com/artist/$username>/albums`) return res.json() > export default async function Page( params: , >: params: < username: string > >) // Initiate both requests in parallel const artistData = getArtist(username) const albumsData = getArtistAlbums(username) // Wait for the promises to resolve const [artist, albums] = await Promise.all([artistData, albumsData]) return ( <> h1>artist.name>h1> Albums list=>Albums> > ) >
By starting the fetch prior to calling await in the Server Component, each request can eagerly start to fetch requests at the same time. This sets the components up so you can avoid waterfalls.
We can save time by initiating both requests in parallel, however, the user won’t see the rendered result until both promises are resolved.
To improve the user experience, you can add a suspense boundary to break up the rendering work and show part of the result as soon as possible:
import < getArtist, getArtistAlbums, type Album > from './api' export default async function Page( params: , >: params: < username: string > >) // Initiate both requests in parallel const artistData = getArtist(username) const albumData = getArtistAlbums(username) // Wait for the artist's promise to resolve first const artist = await artistData return ( <> h1>artist.name>h1> /* Send the artist information first, and wrap albums in a suspense boundary */> Suspense fallback=<div>Loading. div>>> Albums promise= /> Suspense> > ) > // Albums Component async function Albums( : < promise: PromiseAlbum[]> >) // Wait for the albums promise to resolve const albums = await promise return ( ul> albums.map((album) => ( li key=album.id>>album.name>li> ))> ul> ) >
Take a look at the preloading pattern for more information on improving components structure.
Sequential Data Fetching
To fetch data sequentially, you can fetch directly inside the component that needs it, or you can await the result of fetch inside the component that needs it:
// . async function Playlists( artistID >: artistID: string >) // Wait for the playlists const playlists = await getArtistPlaylists(artistID) return ( ul> playlists.map((playlist) => ( li key=playlist.id>>playlist.name>li> ))> ul> ) > export default async function Page( params: , >: params: < username: string > >) // Wait for the artist const artist = await getArtist(username) return ( <> h1>artist.name>h1> Suspense fallback=<div>Loading. div>>> Playlists artistID=artist.id> /> Suspense> > ) >
By fetching data inside the component, each fetch request and nested segment in the route cannot start fetching data and rendering until the previous request or segment has completed.
Blocking Rendering in a Route
By fetching data in a layout, rendering for all route segments beneath it can only start once the data has finished loading.
In the pages directory, pages using server-rendering would show the browser loading spinner until getServerSideProps had finished, then render the React component for that page. This can be described as «all or nothing» data fetching. Either you had the entire data for your page, or none.
In the app directory, you have additional options to explore:
- First, you can use loading.js to show an instant loading state from the server while streaming in the result from your data fetching function.
- Second, you can move data fetching lower in the component tree to only block rendering for the parts of the page that need it. For example, moving data fetching to a specific component rather than fetching it at the root layout.
Whenever possible, it’s best to fetch data in the segment that uses it. This also allows you to show a loading state for only the part of the page that is loading, and not the entire page.
Data Fetching without fetch()
You might not always have the ability to use and configure fetch requests directly if you’re using a third-party library such as an ORM or database client.
In cases where you cannot use fetch but still want to control the caching or revalidating behavior of a layout or page, you can rely on the default caching behavior of the segment or use the segment cache configuration.
Default Caching Behavior
Any data fetching libraries that do not use fetch directly will not affect caching of a route, and will be static or dynamic depending on the route segment.
If the segment is static (default), the output of the request will be cached and revalidated (if configured) alongside the rest of the segment. If the segment is dynamic, the output of the request will not be cached and will be re-fetched on every request when the segment is rendered.
Good to know: Dynamic functions like cookies() and headers() will make the route segment dynamic.
Segment Cache Configuration
As a temporary solution, until the caching behavior of third-party queries can be configured, you can use segment configuration to customize the cache behavior of the entire segment.
import prisma from './lib/prisma' export const revalidate = 3600 // revalidate every hour async function getPosts() const posts = await prisma.post.findMany() return posts > export default async function Page() const posts = await getPosts() // . >
Read JSON DATA and LOAD using JavaScript Async Await
In this JavaScript tutorial you will learn how to load JSON Data from a JSON file and load the JSON data in to HTML drop down list using JavaScript Async await callback functions.
Table of content
- Starter code
- Create a DB folder and a JSON file within the DB with the following data
- How to validate JSON format
- Add new style-json.css to the project
- Create a new javascript file to read JSON
- Load JSON data using async await
- Use .then() to load the json data
- Previous Project : State City Country Zip Code Drop Down code
Starter code
To get started with this javascript project, please create a new Project folder where you can copy and paste the starter code. The code for this project is split into multiple section so please tace care to copy it in correctly into each file.
At the end of the project you will find to complete code.
index.html code
The html file contains code from a previous project witch you can find here, as a blog post with source code, or you can watch the video version .
Down before the body closing tag you need to replace the ` ` with the newly created in order to load the new script file for this project.
Select Country State City Zip
Create a DB folder and a JSON file within the DB with the following data
Create a new folder with the name of DB (data base, this is completely optional) and in this folder or outside of the folder create a JSON file and name it “data.json”.
The path will be later on relevant in your async code
How to validate JSON format
Now that you have your “data.json” file created it is time to populate it with some data. We are going to take the data from our previous project and add it to your JSON file.
var countryStateInfo = < USA: < California: < "Los Angeles": ["90001", "90002", "90003", "90004"], "San Diego": ["92093", "92101"], >, Texas: < Dallas: ["75201", "75202"], Austin: ["73301", "73344"], >, >, Germany: < Bavaria: < Munich: ["80331", "80333", "80335", "80336"], Nuremberg: ["90402", "90403", "90404", "90405"], >, Hessen: < Frankfurt: ["60306", "60308", "60309", "60310"], Surat: ["55246", "55247", "55248", "55249"], >, >, >;
This will result in a erro. Sorry :), the problem is that this is not json code.
But don’t worry, here is the solution. You can validate any code if it is valid json code by following this link for the JSON validator.
Your final VALID JSON code should look something like this. The you can Load JSON with JavaScript
Add new style-json.css to the project
I changed up the style of this project just a little bit.
Create a new style-json.css file and copy the code below
* < margin: 0; padding: 0; font-family: "Open Sans", sans-serif; >h1 < margin-top: 4rem; text-align: center; font-size: 3rem; >body < background-color: #0a1853; color: #f9f9f9; >.dropdown-group < width: 200px; display: flex; flex-direction: column; gap: 20px; margin: auto; margin-top: 15vh; >select < width: 100%; min-width: 15ch; max-width: 30ch; border-radius: 0.25em; padding: 0.25em 0.5em; font-size: 1.25rem; cursor: pointer; line-height: 1.1; background-color: #fff; box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.2); transition: 0.2s ease; >select:hover < transform: scale(1.15); transition: 0.2s ease; >select:focus < border: 2px solid rgb(2, 255, 10); box-shadow: 0px 0px 15px 4px rgba(0, 0, 0, 0.5); transition: 0.2s ease; >option
Create a JavaScript file to read JSON
Now you need to create a loadJSON.js file where you will write the loading functions for the json code.
Copy in the code from the previous video that takes care of the form.
window.onload = function () < const countrySelection = document.querySelector("#Country"), stateSelection = document.querySelector("#State"), citySelection = document.querySelector("#City"), zipSelection = document.querySelector("#Zip"); stateSelection.disabled = true; citySelection.disabled = true; zipSelection.disabled = true; for (let country in countryStateInfo) < countrySelection.options[countrySelection.options.length] = new Option( country, country ); >// todo: Country Change countrySelection.onchange = (e) => < stateSelection.disabled = false; // todo: Clear all options from state selection stateSelection.length = 1; citySelection.length = 1; zipSelection.length = 1; for (let state in countryStateInfo[e.target.value]) < stateSelection.options[stateSelection.options.length] = new Option( state, state ); >>; // todo: State Change stateSelection.onchange = (e) => < citySelection.disabled = false; citySelection.length = 1; zipSelection.length = 1; for (let city in countryStateInfo[countrySelection.value][e.target.value]) < citySelection.options[citySelection.options.length] = new Option( city, city ); >>; // todo: City Change citySelection.onchange = (e) => < zipSelection.disabled = false; zipSelection.length = 1; let zips = countryStateInfo[countrySelection.value][stateSelection.value][ e.target.value ]; for (let i = 0; i < zips.length; i++) < zipSelection.options[zipSelection.options.length] = new Option( zips[i], zips[i] ); >>; >;
Load JSON data using async await
At the start of the window.onload = function () <> is where you will create your asynchronous code that will load the JSON file using the await and fetch function.
Remember to create the code as the start of the function.
window.onload = function () < async function getCountryStateInfo() < const response = await fetch("data2.json"); const data = await response.json(); console.log(data); return data; >getCountryStateInfo(); . >
Initiate the function and open up your console in the browser where you should see your data loading using the console.log.
After you checked that the code loads you can comment out the console log and return the data.
Use .then() to load the json data
After you successfully loaded your JSON data you can now add the .then() method to the getCountryStateInfo() function.
Remember that the then() method returns a Promise . It takes up to two arguments: callback functions for the success and failure cases of the Promise . This mean that you must pass in the data.
getCountryStateInfo().then((data) =>
I suggest that you re-assign the data to a new variable called const countryStateInfo = data; in order to avoid replacing it in your future code.
Now you can move the rest of the code in your callback function and you should see your data from the JSON file being outputted in the form.
Thank you for your time
Hope you enjoyed this short HTML CSS and JavaScript Project, if you did then plase share it with others.
Video Tutorial
Check out the video tutorial for this post for a more detailed and visual explanation .
Latest Udemy Courses
Coupon codes for all courses are already applied in order for you to have the best price possible !