Dynamic Filtering items with prisma and Nextjs?

Oi everyone! I use prisma in combination with Nextjs and mongodb on a project that deals with animal adoption. Namely, now I would like to do dynamic filtering by certain categories and enable it to interact with the user on the client side. Well, I'm interested in whether it's feasible to do it using prism, since I found out through the documentation that I can filter out certain things via the where: { } query. Any help and suggestions on how to do this are welcome. Thank you all!
50 Replies
James4u
James4u2mo ago
yeah, you can @tom_bombadil I can recommend best libraries for your case
James4u
James4u2mo ago
https://nuqs.47ng.com/ this library will be very helpful for you to store values for filtering in the url
nuqs | Type-safe search params state management for Next.js
Type-safe search params state management for Next.js. Like React.useState, but stored in the URL query string.
James4u
James4u2mo ago
and then in your server component you can use prisma to fetch your data while filtering out by query params in the url. let me know if you have any questions
tom_bombadil
tom_bombadil2mo ago
@James4u thank you for answer! Allow me to explain to you what the current situation is on my project, so you can perhaps explain to me 'closer' in which direction I should go. Actually, I have specifically 4 filters, i.e. 4 categories by which I want to filter the items from the array that I display, which are (category: Dog, Cat, Others; location: some cities; ages: young, adult; gender: female and male) . What I managed to do with prisma is that when I set it up in the function on the server side like this: export async function getAdoptPost( context: any, location?: string, ) { const page = parseInt((context.query.page as string) || "1", 12); const pageSize = 12; const total = await db.adoptAnimal.count({}); const post = await db.adoptAnimal.findMany({ skip: (page - 1) * pageSize, take: pageSize, where: { location: location, }, orderBy: { createdAt: "desc", }, }); return { post, page, pageSize, total, }; } this is an example where I only put 'location' as one of the possible options in the filter and now on the client side if I call this function 'getAdoptPost' and assign it 'location' something like this: const [location, setLocation] = useState<string>("Boston"); const fetchData = (page: number) => { startTransition(async () => { const result = await getAdoptPost({ query: { page }, location, }); setPosts(result.post); setPage(result.page); setPageSize(result.pageSize); setLocation(location); setTotal(result.total); setIsLoading(false); // Set loading to false after data is fetched console.log(result); console.log(location); }); }; because of this state, in which I hard-coded the location 'Boston', it will filter out all the animals that have that location on them, but I would like to make it so that the user selects that location via the filter below, and I get the results.
James4u
James4u2mo ago
are you doing client side data-fetching?
tom_bombadil
tom_bombadil2mo ago
that I also have a FIlterMenu component on the client side where there are fields with filters and through these fields I collect the data that the user picks up from the filter. And this is a function that is called on the submit FIlterMenu and I put all those filters that the user selects in the 'allFilters' array export const updateFilters = async (formData: FormData) => { const categoryFilters = formData.getAll("category"); const locationFilters = formData.getAll("location"); const spolFilters = formData.getAll("spol"); const starostFilters = formData.getAll("starost"); const allFilters = [ ...categoryFilters, ...locationFilters, ...spolFilters, ...starostFilters, ]; console.log("all filters", allFilters); if (allFilters.length > 0) { const params = new URLSearchParams([ ["category", categoryFilters.join(",")], ["location", locationFilters.join(",")], ["spol", spolFilters.join(",")], ["starost", starostFilters.join(",")], ]); console.log("params", params); redirect(/adoptPet?${params.toString()}); } else { redirect("/adoptPet"); } }; Is this looks well?
James4u
James4u2mo ago
sorry @tom_bombadil can you format your code?
export const updateFilters = async (formData: FormData) => {
const categoryFilters = formData.getAll("category");
const locationFilters = formData.getAll("location");
const spolFilters = formData.getAll("spol");
const starostFilters = formData.getAll("starost");

const allFilters = [
...categoryFilters,
...locationFilters,
...spolFilters,
...starostFilters,
];

console.log("all filters", allFilters);

if (allFilters.length > 0) {
const params = new URLSearchParams([
["category", categoryFilters.join(",")],
["location", locationFilters.join(",")],
["spol", spolFilters.join(",")],
["starost", starostFilters.join(",")],
]);
console.log("params", params);
redirect(/adoptPet?${params.toString()});
} else {
redirect("/adoptPet");
}
};
export const updateFilters = async (formData: FormData) => {
const categoryFilters = formData.getAll("category");
const locationFilters = formData.getAll("location");
const spolFilters = formData.getAll("spol");
const starostFilters = formData.getAll("starost");

const allFilters = [
...categoryFilters,
...locationFilters,
...spolFilters,
...starostFilters,
];

console.log("all filters", allFilters);

if (allFilters.length > 0) {
const params = new URLSearchParams([
["category", categoryFilters.join(",")],
["location", locationFilters.join(",")],
["spol", spolFilters.join(",")],
["starost", starostFilters.join(",")],
]);
console.log("params", params);
redirect(/adoptPet?${params.toString()});
} else {
redirect("/adoptPet");
}
};
tom_bombadil
tom_bombadil2mo ago
yes I do there is also some extra code related to onSubmit in the FilterMenu, ignore it for now because I'm calling the 'actions' function 'updateFilters' on onSubmit right now
James4u
James4u2mo ago
you mean, you use server actions?
tom_bombadil
tom_bombadil2mo ago
yes, that 'updateFilters' function is on the server side should I use classic handleSubmit in the Filter Menu? or this is fine?
James4u
James4u2mo ago
server actions are for data mutation indeed - you are just redirecting right? you can do that in the client side
tom_bombadil
tom_bombadil2mo ago
this is the log of that updateFilters function: all filters [ 'Macka', 'Tuzla', 'Zensko', 'Odraslo' ] params URLSearchParams { 'category' => 'Macka', 'location' => 'Tuzla', 'spol' => 'Zensko', 'starost' => 'Odraslo' } middleware is running on route: /adoptPet GET /adoptPet?category=Macka&location=Tuzla&spol=Zensko&starost=Odraslo 200 in 29ms in 'allFilters' I place what the user has chosen as a filter and then fill in the pathname as you can see below
James4u
James4u2mo ago
@tom_bombadil sorry but you are not answering my questions - difficult to keep conversation in efficient way
tom_bombadil
tom_bombadil2mo ago
what questions?
James4u
James4u2mo ago
checked this?
Want results from more Discord servers?
Add your server