Next.js Discord

Discord Forum

fetch in server

Answered
Lesser Scaup posted this in #help-forum
Open in Discord
Lesser ScaupOP
im trying to use normal fetching in server

export default async function page({
    params,
}: {
    params: Promise<{ id: string }>;
}) {
    const { id } = await params;

    const res = await fetch(`http://localhost:3000/api/trial/${id}`, {
        cache: 'no-store',
    });

    if (!res.ok) {
        return <>error</>;
    }

    const trial = await res.json();
    console.log(trial);

    return (
        <div className={styles.trial}>
            <>{trial}</>
        </div>
        )}

i create simple route

// api/trial/[id]/route.ts
import { fetchTrialById } from '@/utils/algolia';
import { NextRequest, NextResponse } from 'next/server';

export async function GET(
    req: NextRequest,
    { params }: { params: { id: string } }
) {
    const trialId = params.id;

    // const data = await fetchTrialById(trialId);
    // return NextResponse.json(data);
    try {
        return NextResponse.json({ trialId });
    } catch (err) {
        console.log('err', err);
    }
}

but i keep getting error

im using next15
so i made the params async and i tried in the route to make the samle but keep getting error,
and i tried to make it only /api/tria/${id}

does anyone know what im doing wrong?
Answered by LuisLl
Also, that whole Route Handler isn’t even needed, you can directly do this in your server component (you’re already on the server)

export default async function Page({
    params,
}: {
    params: Promise<{ id: string }>;
}) {
    const { id } = await params;

    const trial = await fetchTrialById(id);

    if (!trial) {
        // here you could do this
        // return notFound();

        return <>error</>;
    }

    return (
        <div className={styles.trial}>
            <>{trial}</>
        </div>
        )}
View full answer

6 Replies

params need to be a promise and be awaited in both the Page Component and the Route Handler.

Here you’re only accessing params as a promise in the component.
Also, that whole Route Handler isn’t even needed, you can directly do this in your server component (you’re already on the server)

export default async function Page({
    params,
}: {
    params: Promise<{ id: string }>;
}) {
    const { id } = await params;

    const trial = await fetchTrialById(id);

    if (!trial) {
        // here you could do this
        // return notFound();

        return <>error</>;
    }

    return (
        <div className={styles.trial}>
            <>{trial}</>
        </div>
        )}
Answer
Now, that fetchTrialById() function can handle the success and error cases, encapsulate the logic.

Could also check for permissions and if you’re not authorized to fetch the trials then just either throw an error and catch it in error.tsx, or return null, or redirect to “/login” or do whatever fits best for your case.
Lesser ScaupOP
yes i get rid of the api/route, i made straight forward, i was trying to do it this way only to practice it,
yes im gonna add later authentication
thank you
@Lesser Scaup thank you
You’re welcome, happy to help :p