'What does this error say? Type 'ParsedQs' is not assignable to type 'string'
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)
Solution 1:[1]
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
Solution 2:[2]
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.
Solution 3:[3]
Adding as any like as below might help you -
Company.find({ $text: { $search: req.query as any} }).exec((err, docs) => {
-------------
-------------
-------------
Solution 4:[4]
req.query is an object that contains all of query parameters you specified in the query.
If your request looks like this
test.com/search/?s=something
something will be stored in req.query.s.
The second option is to use named route parameters. So you can set do this:
Request URL
test.com/search/something
Route
app.get('/search/:search', (req, res) => {
console.log(req.params.search); // "something". NB use req.params, not req.query
})
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Richard Torcato |
| Solution 3 | Pradeep |
| Solution 4 | F'1 |
