Hello my problem is I want to use the search query of mongoose. But I want to make a get request using a query. Why is that not possible? I do not understand this error. I am using version 5.10.0 of mongoose. I don't want to do it as a post request and I would not like to use req.body. Can anyone help me?
here my code:
export const searching = (req: Request, res: Response) => {
Company.find({ $text: { $search: req.query } }).exec((err, docs) => {
if (docs) {
res.status(200).json(docs)
} else {
console.log(err)
}
})
}
my error message:
(property) $search: string
No overload matches this call.
The last overload gave the following error.
Type 'ParsedQs' is not assignable to type 'string'.ts(2769)
req.query is an object containing request query
So if you send a request to the endpoint like this /?foo=bar&a=123
You can access the query value from
req.query.foo // bar
req.query.a // 123
You are passing query object to the $search, meanwhile you are supposed to pass a string, so it should be
Company.find({ $text: { $search: req.query.yourQueryKey as string } }).exec((err, docs) => {
Better solution is to type your RequestHandler function
import {RequestHandler} from "express";
type Params = {};
type ResBody = {};
type ReqBody = {};
type ReqQuery = {
query: string;
}
export const searching: RequestHandler<Params, ResBody, ReqBody, ReqQuery> = (req, res) => {
const query = req.query.query; // string
}
Even better solution: type your RequestHandler function and use a validation library to validate the request query like joi or celebrate
You are passing req.query to your search and the default Typescript type for req.query is
Request<unknown, unknown, unknown, QueryString.ParsedQs, Record<string, any>>.query: QueryString.ParsedQs
and if you passed in req.query.searchText the type for that would be
string | QueryString.ParsedQs | string[] | QueryString.ParsedQs[] | undefined
The simple way is already answered here just do
export const searching = (req: Request, res: Response) => {
const searchText = req.query. searchText as string
Company.find({ $text: { $search: searchText } }).exec((err, docs) => {
if (docs) {
res.status(200).json(docs)
} else {
console.log(err)
}
})
}
That works but gets sloppy when you have a lot of variables from your query params. In express try out the RequestHandler for your endpoints.
import { RequestHandler } from 'express'
interface QueryTypes {
searchText: string
moreSearchText: string
}
export const searching:RequestHandler<unknown, unknown, unknown, QueryTypes > = (req, res) => {
Company.find({ $text: { $search: req.query } }).exec((err, docs) => {
if (docs) {
res.status(200).json(docs)
} else {
console.log(err)
}
})
}
You can see using the RequestHandler I can pass in a few unknown types and the fourth one I can pass in the query types. I can also remove the Request and Response types to just (req, res) because RequestHandler already types out the handler for us.
You're probably wondering what the 3 previous unknown are and that too in the typescript docs for RequestHandler. Here is the docs.
interface RequestHandler<P = core.ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = qs.ParsedQs, Locals extends Record<string, any> = Record<string, any>>
Now using RequestHandler. I can type out parameters, body, reqbody or query. Use a combo or skip them using unknown like I did in my example.
This also has the added benefit of giving you type safety so
const test = req.query.test
would highlight a typescript error in vscode for me because 'test' is defined in my QueryTypes interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With