Issue
I am working on a Next.js 14 project with TypeScript and creating a blog using AWS Amplify Gen 2 and GraphQL. In my application, I need to retrieve specific data based on the path name of the URL. Here's what I have so far:
I'm using a component named Article:
'use client';
import { usePathname } from "next/navigation";
export default function Article() {
const slug = usePathname().split('/').pop();
return slug;
}
I have a page.tsx file under app/articles/[slug]:
import type { Schema } from '@/amplify/data/resource';
import { generateClient } from 'aws-amplify/data';
import Article from '@/components/article/article';
const client = generateClient<Schema>();
async function fetchPosts() {
const { data: posts } = await client.models.Posts.list();
return posts;
}
export default async function ArticlePage() {
const posts = await fetchPosts();
return (
// I need to return the posts that match the slug value in the URL path
);
}
I want to modify ArticlePage so that it fetches and returns the posts that match the slug value from the URL path. How can I achieve this?
I'm using Next.js 14 and TypeScript.
The client.models.Posts.list()
function retrieves all the posts, and I need to filter them based on the slug value from the URL path.
EDIT:
This code below does the trick, but instead of a String, I need it to be the URL path /articles/my-first-post or /articles/my-second-post.
import type { Schema } from '@/amplify/data/resource';
import { generateClient } from 'aws-amplify/data';
const client = generateClient<Schema>();
async function fetchPosts() {
const { data: posts, errors } = await client.models.Posts.list();
return posts;
}
export default async function Article() {
const slug = 'my-first-post';
const posts = await fetchPosts();
const filteredPosts = posts.filter(post => post.slug === slug);
return (
<div>
{filteredPosts.map(post => (
<div key={post.createdAt}>
<h2>{post.title}</h2>
<p>{new Date(post.createdAt).toLocaleDateString()}</p>
<p>{post.content}</p>
</div>
))}
</div>
);
}
Solution
Something like:
async function fetchPosts(slug) {
const { data: posts } = await client.models.Posts.list();
return posts.filter((p) => p.id === slug); // or whatever you need to match
}
export default async function ArticlePage({ params }: { params: { slug: string } }) {
const posts = await fetchPosts(params.slug);
return (
...
);
}
probably would do the trick. You don't need the code from Article
component then.
However, I would probably do the filtering inside with client.models.Posts.list(slug)
and fetch only the relevant ones. It would be more efficient.
Answered By - grekier
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.