Next.js Discord

Discord Forum

Cannot get joined data in fetch result (server component, app router)

Unanswered
Great Dane posted this in #help-forum
Open in Discord
Great DaneOP
The fetch request in the server component returns the response without joined data (one-to-many relationship). I use the construction from the docs:
async function getData(slug: string) {
  const res = await fetch(`${HOST}/api/pub/news/${slug}`);
  if (!res.ok) {
    throw new Error("Failed to fetch data");
  }
  return res.json();
}

The usual request to the API on the client side returns the following answer:
{
  title: "Some title",
  img: "path_to_image",
  createdAt: "some date",
  comments: [
    ...some comments
  ]
}

However, the request in the server component does not give comments in the payload. Can this be fixed?

8 Replies

New Guinea Singing Dog
Can you send the code for your API?
Great DaneOP
Hello! This is how the answer looks like:
[
  {
    "id": 308,
    "dir": "1i/1iu4f5fwxcugf5znc83i-855d44a5cc60ade9bbfe409d7fdc4bb6",
    "title": "I am Shutruk Nahunte, King of Anshand and Susa",
    "text": "I am Shutruk Nahunte, King of Anshand and Susa, Sovereign of the land of Elam. By the command of Inshushinak I destroyed Sippar, Took the Stele of Niran-Sin, and brought it back to Elam, where I erected it as an offering to my god, Inshushhinak.",
    "photos": ["8jsxbx4ejfh8n9niyda2.jpg"],
    "video": null,
    "youtube": null,
    "createdAt": "2023-09-02T15:22:03.382Z",
    "tags": ["news", "it"],
    "sourceurl": "https://www.rbc.ru/rbcfreenews/64f3360c9a79479accf9fa86",
    "looks": 66,
    "authorId": 1,
    "authorname": "Admin",
    "authorphotos": ["zcnx1kl4ip7s3sbnuluh.jpg"],
    "authordir": "ss/ssfvf5fsr9or8vfqiq7y-64443e80c8552cb29819106b1db44d3e",
    "comment": [
      {
        "id": 5,
        "text": "<p>Ab imo pectore</p>",
        "dir": null,
        "img": null,
        "createdAt": "2023-10-03T02:34:30.789553",
        "author": {
          "id": 1,
          "title": "Admin",
          "photos": ["zcnx1kl4ip7s3sbnuluh.jpg"],
          "dir": "ss/ssfvf5fsr9or8vfqiq7y-64443e80c8552cb29819106b1db44d3e"
        }
      },
      {
        "id": 6,
        "text": "<p>Shutruk-Nahhunte</p>",
        "dir": null,
        "img": null,
        "createdAt": "2023-10-03T03:04:07.43339",
        "author": {
          "id": 1,
          "title": "Admin",
          "photos": ["zcnx1kl4ip7s3sbnuluh.jpg"],
          "dir": "ss/ssfvf5fsr9or8vfqiq7y-64443e80c8552cb29819106b1db44d3e"
        }
      }
    ]
  }
]
The code is quite large. Here is the server component:
import NodataSingle from "@/components/NodataSingle";
import { imgProps } from "@/misc/stools";
import { IPost } from "@/misc/types";
import Post from "@/wrappers/Post";
import { Metadata, ResolvingMetadata } from "next";
import React from "react";

const HOST = process.env.NEXT_PUBLIC_HOST;

type Props = {
  params: { slug: string };
  searchParams: { [key: string]: string | string[] | undefined };
};

export async function generateMetadata(
  { params, searchParams }: Props,
  parent: ResolvingMetadata,
): Promise<Metadata> {
  const slug = params.slug;

  const data: IPost[] = await fetch(`${HOST}/api/pub/news/${String(slug)}`, {
    cache: "no-store",
  })
    .then((res) => res.json())
    .catch((err) => {
      throw new Error("Failed to fetch data");
    });

  const content = data[0];

  return {
    metadataBase: new URL(String(HOST)),
    title: content.title,
    description: content.text?.slice(0, 50) + "...",
    openGraph: {
      url: `${HOST}/news/${slug}`,
      title: content.title,
      description: content.text?.slice(0, 50) + "...",
      images:
        content.photos && content.dir
          ? content.photos.map((x) => {
              return {
                url: `/dist/${content.dir}/${x}`,
                ...imgProps(content.title),
              };
            })
          : [
              {
                url: "/dist/common/main.jpg",
                ...imgProps(content.title),
              },
            ],
    },
  };
}

async function getData(slug: string) {
  const res = await fetch(`${HOST}/api/pub/news/${slug}`, {
    cache: "no-store",
  });
  if (!res.ok) {
    throw new Error("Failed to fetch data");
  }

  return res.json();
}

export default async function Page({ params, searchParams }: Props) {
  const { slug } = params;
  const data = await getData(slug);

  if (data) {
    return <Post data={data[0]} slug={slug} />;
  } else return <NodataSingle />;
}
@Great Dane The code is quite large. Here is the server component: import NodataSingle from "@/components/NodataSingle"; import { imgProps } from "@/misc/stools"; import { IPost } from "@/misc/types"; import Post from "@/wrappers/Post"; import { Metadata, ResolvingMetadata } from "next"; import React from "react"; const HOST = process.env.NEXT_PUBLIC_HOST; type Props = { params: { slug: string }; searchParams: { [key: string]: string | string[] | undefined }; }; export async function generateMetadata( { params, searchParams }: Props, parent: ResolvingMetadata, ): Promise<Metadata> { const slug = params.slug; const data: IPost[] = await fetch(`${HOST}/api/pub/news/${String(slug)}`, { cache: "no-store", }) .then((res) => res.json()) .catch((err) => { throw new Error("Failed to fetch data"); }); const content = data[0]; return { metadataBase: new URL(String(HOST)), title: content.title, description: content.text?.slice(0, 50) + "...", openGraph: { url: `${HOST}/news/${slug}`, title: content.title, description: content.text?.slice(0, 50) + "...", images: content.photos && content.dir ? content.photos.map((x) => { return { url: `/dist/${content.dir}/${x}`, ...imgProps(content.title), }; }) : [ { url: "/dist/common/main.jpg", ...imgProps(content.title), }, ], }, }; } async function getData(slug: string) { const res = await fetch(`${HOST}/api/pub/news/${slug}`, { cache: "no-store", }); if (!res.ok) { throw new Error("Failed to fetch data"); } return res.json(); } export default async function Page({ params, searchParams }: Props) { const { slug } = params; const data = await getData(slug); if (data) { return <Post data={data[0]} slug={slug} />; } else return <NodataSingle />; }
New Guinea Singing Dog
I was more asking about the api code, where you're fetching
const res = await fetch('/${HOST}/api/pub/news/${slug}')

Do you have the code for that endpoint?
Great DaneOP
It's fixed by "cache: no store". But is it the right solution???
New Guinea Singing Dog
Well if it works it works 😆
Great DaneOP
OK then. Thanks!