Reputation: 1248
I am trying to implement search functionality in Node, mongoose.
There is two parameter I like to search upon, either by name or artist. If any of the two matches with the current database it should return value(making it restful)
However, it is sending response Error: Can't set headers after they are sent.
and Unhandled promise rejections are deprecated
and even the response which i am getting is empty
I am trying to execute two queries in it, which i think might be the problem. How should i write it, or what is a correct way to write these type of functionality
Here is my current code
app.get('/search/:textValue', controller.findData)
and the findData
exports.findData = (req, res)=>{
const searchParam = req.params.textValue;
let storeResult = []
if(searchParam==null|| searchParam == undefined || searchParam==""){
return res.status(500).json("Send a valid input")
}
else{
Song.find({artists: new RegExp(searchParam, "i")}).lean().then((data)=>{
storeResult[0].push(data)
}).catch((err)=>{
return res.send(err)
})
Song.find({name: new RegExp(searchParam, "i")}).lean().then((data)=>{
storeResult[1].push(data)
}).catch((err)=>{
return res.send(err)
})
return res.send(storeResult)
}
}
They are working for single queries perfectly fine, what changes should be made over here ?
Upvotes: 1
Views: 62
Reputation: 4116
Problem
let storeResult = []
storeResult[0].push(data)
catch
callback. And then do a res.send(err)
return
it will still continue in (req, res) => {}
. This is because the return
is only for the (err) => { // }
callbackstoreResult[1].push(data)
return res.send(storeResult)
which effectively finishes your (req, res) => {}
callback and return another response to the clientSolution:
When you push to your storeResult
array, omit the index. Like this
storeResult.push(data)
Note
Even when pushing correctly, an error might happen while accessing the database. This is why you also need to chain your callbacks like O. Jones answer says
Upvotes: 1
Reputation: 108651
The way you have it you're using res.send(storeResult)
before you fill in storeResult
. How so? You fill it in with your .then()
callbacks, which haven't yet been invoked.
Try chaining your then
callbacks.
Song.find({artists: new RegExp(searchParam, "i")}).lean()
.then((data)=>{
storeResult.push(data);
})
.then(() => {
Song.find({name: new RegExp(searchParam, "i")}).lean()
.then((data)=>{
storeResult.push(data)
})
.then(() => {
console.log(storeResult)
res.send(storeResult)
})
})
.catch((err)=>{
console.log("Here is error")
console.log(err)
res.send(err)
})
}
Hint. Step-into in your debugger is useful for troubleshooting this kind of code.
Upvotes: 1
Reputation: 978
Try this:
exports.findData = (req, res)=>{
let count=0;
const searchParam = req.params.textValue;
let storeResult = []
if(searchParam==null|| searchParam == undefined || searchParam==""){
return res.status(500).json("Send a valid input")
}
else{
Song.find({artists: new RegExp(searchParam, "i")}).lean().then((data)=>{
storeResult[0].push(data)
}).catch((err)=>{
count++;
return res.send(err)
})
if(count == 0) {
Song.find({name: new RegExp(searchParam, "i")}).lean().then((data)=>{
storeResult[1].push(data)
}).catch((err)=>{
count++;
return res.send(err)
})
}
if(count == 0) {
return res.send(storeResult)
}
}
}
Upvotes: 1