Edit: I've confirmed the issue is in my validateToken
middleware and have appended that code to the bottom.
I am creating a ToDo application that utilizes a node back-end and MongoDB to store user accounts/data and am having difficulties fetching a user's stored data.
The front-end issues an API call to /api/todos/fetch on the back-end each time the application is loaded, and it sends the user's token in the Authorization header which is then decrypted to grab the user's username so it can be used to query their data from the database.
Here is the API endpoint, /api/todos/fetch:
router.get('/fetch', validateToken, (req, res) => {
const user = req.decodedJwt.username;
Todo.find({username: user})
.then(data => {
console.log(query)
res.json(data)
})
.catch(err => {
console.log(err)
res.json(err)
})
})
Here is the Todo Schema:
const Todo = new Schema(
{
username: { type: String, required: true, unique: true },
todos: []
},
);
module.exports = mongoose.model('todos', Todo)
The issue I am running into is it seems that Todo.find()
is executing the .then()
before actually resolving the promise, which in Postman is telling me Cannot GET /api/todos/fetch
and in my Node console I am getting Cannot set headers after they are sent to the client
and node:internal/process/promises:246 - triggerUncaughtException(err, true /* fromPromise */);
as well as a lot of other stack feedback.
Todo.find()
is working and grabbing the correct data from the database and I can log it to the console, but it only logs to the console after the HTTP response has been sent which is what's confusing me. My understanding is Todo.find()
will execute and if it is successful, meaning the data was grabbed, then .then(data)
portion will fire with the resolved information, otherwise the .catch(err)
will kick back the error response. I have tried async/await
and try/catch
as well. I've tried pulling the find()
functionality into a separate async helper function. I've done the same db operations with SQLite and PostgreSQL, but this is the first time I've used MongoDB and Mongoose. Sorry if this is redundant or has been asked, I've spent half a dozen hours so far reading through documentation and other user's questions.
Edit: Here is my validateToken
middleware:
module.exports = (req, res, next) => {
const token = req.headers.authorization;
if (token) {
jwt.verify(token, jwtSecret, (err, decoded) => {
if (err) {
console.log("\n!!!~~~Sending response~~~!!!\n")
res.status(401).json('Please supply a valid token')
} else {
req.decodedJwt = decoded;
next();
}
})
} else {
console.log("\n!!!~~~Sending response~~~!!!\n")
res.status(401).json("You must have a token to do that");
}
next();
}
Currently neither of the console.log's are firing when I use the middleware, and the data makes it to the /fetch
endpoint after the middleware.