Next.js Discord

Discord Forum

Instantaneous return of Client-side component while doing some Server-side calls

Unanswered
Picardy Spaniel posted this in #help-forum
Open in Discord
Picardy SpanielOP
I am using Next.js 14.1

Suppose I have this flow of my server-side component page - how can I return the SkeletonLoader instantly while it is calling database services/3rd party APIs?

const getRecordsToShowFromDb = async (session: Session | null) => {
// Logic for calling database services to fetch records
};

const SomPage = async () => {
let contentToRender = <SkeletonLoader />;

const session = await auth();

const getRecordsToShowFromDbRes = await getRecordsToShowFromDb(session);
const allRecords =
(await getRecordsToShowFromDbRes.json()) as SomeObject[];

const someObject: AnotherObjectType = {};
const someObject2: AnotherObjectType2 = {};

for (const record of allRecords) {
const [locationDetails, displayImage] =
await Promise.all([
someApiServiceFn(allRecords.id);
someApiServiceFn2(allRecords.id);
]);
someObject[allRecords.id] = locationDetails;
someObject2[allRecords.id] = displayImage;
}

if (
allRecords &&
allRecords.length > 0 &&
Object.keys(someObject).length > 0 &&
Object.keys(someObject2).length > 0
) {
contentToRender = (
<div className="flex flex-1 px-4 lg:px-0">
<ListComponentTest {...props} />
</div>
);
}

return contentToRender;
};

export default SomPage;

4 Replies

@Picardy Spaniel I am using Next.js 14.1 Suppose I have this flow of my server-side component page - how can I return the SkeletonLoader instantly while it is calling database services/3rd party APIs? const getRecordsToShowFromDb = async (session: Session | null) => { // Logic for calling database services to fetch records }; const SomPage = async () => { let contentToRender = <SkeletonLoader />; const session = await auth(); const getRecordsToShowFromDbRes = await getRecordsToShowFromDb(session); const allRecords = (await getRecordsToShowFromDbRes.json()) as SomeObject[]; const someObject: AnotherObjectType = {}; const someObject2: AnotherObjectType2 = {}; for (const record of allRecords) { const [locationDetails, displayImage] = await Promise.all([ someApiServiceFn(allRecords.id); someApiServiceFn2(allRecords.id); ]); someObject[allRecords.id] = locationDetails; someObject2[allRecords.id] = displayImage; } if ( allRecords && allRecords.length > 0 && Object.keys(someObject).length > 0 && Object.keys(someObject2).length > 0 ) { contentToRender = ( <div className="flex flex-1 px-4 lg:px-0"> <ListComponentTest {...props} /> </div> ); } return contentToRender; }; export default SomPage;
your style of writing code looks a bit unfamiliar to me. i would separate the long await code into another async component, then wrap it in a Suspense on page.tsx's content

// @file page.tsx
const SomPage = async () => {
  const session = await auth();

  return <div className="flex flex-1 px-4 lg:px-0">
    <Suspense fallback={<SkeletonLoader />}>
      <RecordList />
    </Suspense>
  </div>;
};

export default SomPage; 

// @file RecordList.tsx
const getRecordsToShowFromDb = async (session: Session | null) => {
  // Logic for calling database services to fetch records
};

const RecordList = async () => {
  const allRecords =
    await getRecordsToShowFromDbRes.json() as SomeObject[];

  const someObject: AnotherObjectType = {};
  const someObject2: AnotherObjectType2 = {};

  for (const record of allRecords) {
    const [locationDetails, displayImage] =
      await Promise.all([
        someApiServiceFn(allRecords.id);
        someApiServiceFn2(allRecords.id);
      ]);
    someObject[allRecords.id] = locationDetails;
    someObject2[allRecords.id] = displayImage;
  }

  return <ListComponentTest {...props} />;
}

export default RecordList;
it's important to note that await blocks the code, it does not make a piece of code to run asynchronously.

here I'm using react's Suspense to render components asynchronously, while letting other components in the page.tsx tree to render.
a video about react suspense if you're interested to learn more https://www.youtube.com/watch?v=8YQXeqgSSeM
next's official site has a very well-explained docs about the topic as well https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming