I am a beginner who wants to build a blog using Notion API, Next.js and Tailwind CSS. I learned the following code from here: https://egghead.io/lessons/next-js-request-notion-database-data-from-the-api-with-next-js.
The following code works fine in /post/index.js
, but I get this error when I put the following code into /components/PostTest.js
and import it in /index.js
.
How do I solve this problem?
Error information
Server Error
TypeError: Cannot read properties of undefined (reading 'map')
#line 9
return posts.map((posts) => (
Source Code
import Head from "next/head";
import Link from "next/link";
import { Client } from "@notionhq/client";
import { useState } from "react";
export const PostPage = ({ posts }) => {
const [post] = useState(null);
return posts.map((posts) => (
<div className="bg-[#F5F5F7] dark:bg-black px-4 py-2 md:py-4">
<div className="bg-[#FFFFFF] dark:bg-[#141414] max-w-sm rounded-xl overflow-hidden shadow-sm container mx-auto">
<img
className="aspect-[16/9] bg-cover bg-center"
src={posts.coverImage}
alt="Post Banner"
/>
<div className="px-6 py-4">
<p className="text-[12px] md:text-[14px] dark:text-[#888888] leading-5 font-[700] pt-2 uppercase tracking-normal mb-[8px]">
{posts.Category}
</p>
<Link href={`/post/${posts.PID}`}>
<div className="text-lg md:text-xl text-[#1d1d1f] dark:text-[#F5F5F7] leading-snug font-[700]">
{posts.Title}
</div>
</Link>
<p className="text-[14px] text-[#6e6e73] dark:text-[#888888] leading-5 font-[600] pt-2">
{new Date(posts.Date).toLocaleDateString()}
</p>
</div>
</div>
</div>
));
};
export const getStaticProps = async () => {
const notion = new Client({
auth: process.env.NOTION_TOKEN,
});
// get posts more than 100 pages.
let results = [];
let data = await notion.databases.query({
database_id: process.env.NOTION_POST_DATABASE_ID,
filter: {
property: "Status",
select: {
equals: "Published",
},
},
sorts: [
{
property: "Date",
direction: "descending",
},
],
});
results = [...data.results];
while (data.has_more) {
data = await notion.databases.query({
database_id: process.env.NOTION_POST_DATABASE_ID,
filter: {
property: "Status",
select: {
equals: "Published",
},
},
start_cursor: data.next_cursor,
});
results = [...results, ...data.results];
}
const posts = results.map((post) => ({
id: post.id,
Title: post.properties.Title.title[0].text.content,
Category: post.properties.Category.select.name,
category_color: post.properties.Category.select.color,
Date: post.properties.Date.date.start,
Tags: post.properties.Tags.multi_select.map((Tags) => Tags.name),
Tags_color: post.properties.Tags.multi_select.map((TagsColor) => TagsColor.color),
PID: post.properties.PID.rich_text[0].text.content,
Author: post.properties.Author.people.map((people) => people.name),
Author_avatar_url: post.properties.Author.people.map((people) => people.avatar_url),
coverImage:
post.cover.file?.url ||
post.cover.external?.url,
}));
return {
props: {
posts,
},
revalidate: 1,
};
};
export default PostPage;
CodePudding user response:
First of all, post
should be inited with an empty array:
const [post, ] = useState([]);
Secondly, you cannot return an array of JSX, so wrap it in a Fragment or <>
.
return (
<>
posts.map((posts) => (
...
)
</>
)
CodePudding user response:
if posts is null or it's not an array, you'll get that error. Try this fix
return (
posts?.map((posts) => (
...
)
)