SeacrhTerm
Answered
AmangLy posted this in #help-forum
AmangLyOP
how to implement, i have create client-side and i need help for mongodb in serverside
// components/SearchForm.tsx
import { useSearchParams, usePathname, useRouter } from "next/navigation";
import { useDebouncedCallback } from "use-debounce";
export default function SearchForm() {
const searchParams = useSearchParams();
const pathname = usePathname();
const { replace } = useRouter();
const handleSearch = useDebouncedCallback((term) => {
console.log(`Searching... ${term}`);
const params = new URLSearchParams(searchParams);
if (term) {
params.set("query", term);
} else {
params.delete("query");
}
replace(`${pathname}?${params.toString()}`);
}, 2000);
return (
<div className="bg-gray-100 rounded-lg mt-8 p-4">
<form className="relative" onSubmit={(e) => e.preventDefault()}>
{/* Input Field */}
<input
type="search"
className="w-full bg-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-600"
placeholder="Search Game"
aria-label="Search game"
onChange={(e) => {
handleSearch(e.target.value);
}}
defaultValue={searchParams.get("query")?.toString()}
/>
{/* Search Button */}
<button type="submit" className="absolute right-0 bottom-2 mt-5 mr-4">
<svg
className="w-6 h-6 text-gray-800 dark:text-black"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 20 20"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"
/>
</svg>
</button>
</form>
</div>
);
}Answered by AmangLy
export const getProducts = async (page: number = 1, pageSize: number = 10, search: string = "") => {
const collection = (await getDB()).collection(COLLECTION_NAME);
const skip = (page - 1) * pageSize;
const query = search ? { name: { $regex: search, $options: "i" } } : {};
const products = await collection.find(query)
.skip(skip)
.limit(pageSize)
.toArray() as ProductModel[];
return products;
};25 Replies
Sure, let me check the code
AmangLyOP
// api/products/route.tsx:
import { getProducts, getProductsBySearchTerm } from "@/app/db/models/products";
import { NextResponse } from "next/server";
export async function GET(request: Request) {
const products = await getProducts();
// console.log(products);
return NextResponse.json(
{
status: 200,
message: "Success get all products",
data: products,
},
{
status: 200,
}
);
}
export async function POST(request: Request) {
const { searchTerm } = await request.json();
const products = await getProductsBySearchTerm(searchTerm);
console.log(products, "<<<<");
return NextResponse.json(
{
status: 200,
message: "Success get all products",
data: products,
},
{
status: 200,
}
);
}
import { getProducts, getProductsBySearchTerm } from "@/app/db/models/products";
import { NextResponse } from "next/server";
export async function GET(request: Request) {
const products = await getProducts();
// console.log(products);
return NextResponse.json(
{
status: 200,
message: "Success get all products",
data: products,
},
{
status: 200,
}
);
}
export async function POST(request: Request) {
const { searchTerm } = await request.json();
const products = await getProductsBySearchTerm(searchTerm);
console.log(products, "<<<<");
return NextResponse.json(
{
status: 200,
message: "Success get all products",
data: products,
},
{
status: 200,
}
);
}
send the function
getProductsBySearchTerm from @/app/db/models/productsAmangLyOP
I'll help you modify it
AmangLyOP
// db/models/products.tsx
import { ObjectId } from "mongodb";
import { getMongoClientInstance } from "../config";
const DB_NAME = "games";
const COLLECTION_NAME = "products";
export type ProductModel = {
_id: ObjectId;
name: string;
slug: string;
description: string;
excerpt: string;
price: number;
tags: string[];
thumbnail: string;
images: string[];
createdAt?: Date;
updatedAt?: Date;
};
export type ProductCreateInputType = Omit<
ProductModel,
"createdAt" | "updatedAt"
>;
const getDB = async () => {
const client = await getMongoClientInstance();
const db = client.db(DB_NAME);
return db;
};
export const getProducts = async () => {
const collection = (await getDB()).collection(COLLECTION_NAME);
const Game = (await collection.find({}).toArray()) as ProductModel[];
return Game;
};
export const getProductsBySearchTerm = async (searchTerm: string) => {
const collection = (await getDB()).collection(COLLECTION_NAME);
const Game = (await collection
.find({ $text: { $search: searchTerm } })
.toArray()) as ProductModel[];
// console.log(Game, "<<<<");
return Game;
};
import { ObjectId } from "mongodb";
import { getMongoClientInstance } from "../config";
const DB_NAME = "games";
const COLLECTION_NAME = "products";
export type ProductModel = {
_id: ObjectId;
name: string;
slug: string;
description: string;
excerpt: string;
price: number;
tags: string[];
thumbnail: string;
images: string[];
createdAt?: Date;
updatedAt?: Date;
};
export type ProductCreateInputType = Omit<
ProductModel,
"createdAt" | "updatedAt"
>;
const getDB = async () => {
const client = await getMongoClientInstance();
const db = client.db(DB_NAME);
return db;
};
export const getProducts = async () => {
const collection = (await getDB()).collection(COLLECTION_NAME);
const Game = (await collection.find({}).toArray()) as ProductModel[];
return Game;
};
export const getProductsBySearchTerm = async (searchTerm: string) => {
const collection = (await getDB()).collection(COLLECTION_NAME);
const Game = (await collection
.find({ $text: { $search: searchTerm } })
.toArray()) as ProductModel[];
// console.log(Game, "<<<<");
return Game;
};
AmangLyOP
nope i search by name
// api/products/route.tsx:
import { getProducts, getProductsBySearchTerm } from "@/app/db/models/products";
import { NextResponse } from "next/server";
export async function GET(request: Request) {
const products = await getProducts();
// console.log(products);
return NextResponse.json(
{
status: 200,
message: "Success get all products",
data: products,
},
{
status: 200,
}
);
}
export async function POST(request: Request) {
const { searchTerm } = await request.json();
const products = await getProductsBySearchTerm(searchTerm);
console.log(products, "<<<<");
return NextResponse.json(
{
status: 200,
message: "Success get all products",
data: products,
},
{
status: 200,
}
);
}@AmangLy nope i search by name
there is another way to achieve this, which works fine, but its not that good. the code seems to be fine, the issue must be with searchSchema
AmangLyOP
yeah
// products/games/page.tsx
"use client";
import GameCard from "@/app/components/GameCard";
import React, { useEffect, useState } from "react";
import GamesLoadingPage from "./loading";
import GameErrorPage from "./error";
import SearchForm from "@/app/components/SearchForm";
interface Game {
_id: string;
name: string;
slug: string;
description: string;
excerpt: string;
price: number;
tags: string[];
thumbnail: string;
images: string[];
}
interface GameSectionProps {
showFullDetails?: boolean;
maxDisplay?: number;
}
const GameSection: React.FC<GameSectionProps> = ({
showFullDetails,
maxDisplay,
}) => {
const [games, setGames] = useState<Game[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
const fetchGames = async () => {
setLoading(true);
setError(null);
try {
const response = await fetch("http://localhost:3000/api/products");
const data = await response.json();
setGames(data.data);
} catch (err) {
setError(err as Error);
} finally {
setLoading(false);
}
};
fetchGames();
}, [error]);
if (loading) {
return <GamesLoadingPage />;
}
if (error) {
return <GameErrorPage error={error} />;
}
return (
<section className="py-12 bg-gray-100">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<SearchForm />
"use client";
import GameCard from "@/app/components/GameCard";
import React, { useEffect, useState } from "react";
import GamesLoadingPage from "./loading";
import GameErrorPage from "./error";
import SearchForm from "@/app/components/SearchForm";
interface Game {
_id: string;
name: string;
slug: string;
description: string;
excerpt: string;
price: number;
tags: string[];
thumbnail: string;
images: string[];
}
interface GameSectionProps {
showFullDetails?: boolean;
maxDisplay?: number;
}
const GameSection: React.FC<GameSectionProps> = ({
showFullDetails,
maxDisplay,
}) => {
const [games, setGames] = useState<Game[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
const fetchGames = async () => {
setLoading(true);
setError(null);
try {
const response = await fetch("http://localhost:3000/api/products");
const data = await response.json();
setGames(data.data);
} catch (err) {
setError(err as Error);
} finally {
setLoading(false);
}
};
fetchGames();
}, [error]);
if (loading) {
return <GamesLoadingPage />;
}
if (error) {
return <GameErrorPage error={error} />;
}
return (
<section className="py-12 bg-gray-100">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<SearchForm />
@AmangLy yeah
Is your issue resolved? And if it’s not working. I can give you a alternate solution, which is a little ineffective
AmangLyOP
just give me alternate solution i think i can recognize
@AmangLy just give me alternate solution i think i can recognize
const products = await this.Products.find({
name: {
$regex: sanitizedQuery,
$options: "i"
}
}, { orders: 0, sizes: 0 }).sort({ orders: -1 }).limit(limit).exec()this is what I've used
@AmangLy just give me alternate solution i think i can recognize
Is your issue resolved?
Hey @AmangLy , I'm awaiting your reply
@AmangLy
Is your issue resolved?
AmangLyOP
export const getProducts = async (page: number = 1, pageSize: number = 10, search: string = "") => {
const collection = (await getDB()).collection(COLLECTION_NAME);
const skip = (page - 1) * pageSize;
const query = search ? { name: { $regex: search, $options: "i" } } : {};
const products = await collection.find(query)
.skip(skip)
.limit(pageSize)
.toArray() as ProductModel[];
return products;
};Answer
AmangLyOP
i use like this solved
@Anay-208 js
const products = await this.Products.find({
name: {
$regex: sanitizedQuery,
$options: "i"
}
}, { orders: 0, sizes: 0 }).sort({ orders: -1 }).limit(limit).exec()
Hold/right click this message, apps, mark solution