I created a filter system API typescript express node mongoose, and there is an error in my code (Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client), is there anyone who will be able to help me, attached the controller code, utils and the error. Thank you.
Utils.ts
class sortPageUtils {
constructor() { }
paginateArray(array: any, perPage: any, page: any) {
return array.slice((page - 1) * perPage, page * perPage)
}
sortCompare(key: any) {
return (a: any, b: any) => {
const fieldA = a[key]
const fieldB = b[key]
let comparison = 0
if (fieldA > fieldB) {
comparison = 1
} else if (fieldA < fieldB) {
comparison = -1
}
return comparison
}
}
}
const sort_Page = new sortPageUtils()
export default sort_Page
Controller.ts
GetAllUsers = (req: Request, res: Response, query: any) => {
Users.find(query || {})
.then(user => {
// search and pagination with params config
const {
q = '',
perPage = 10,
page = 1,
sortBy = '_id',
sortDesc = false,
} = req.query;
const queryLowered = q.toLowerCase()
const filteredData = user.filter(item => {
item.nom.toLowerCase().includes(queryLowered) || item.prenom.toLowerCase().includes(queryLowered) || item.telephone.toLowerCase().includes(queryLowered) || item.email.toLowerCase().includes(queryLowered) || item.role.toLowerCase().includes(queryLowered)
})
const sortedData = filteredData.sort(sort_Page.sortCompare(sortBy))
if (sortDesc) sortedData.reverse()
res.setHeader('Content-Type', 'application/json');
res.status(200).json({
users: sort_Page.paginateArray(sortedData, perPage, page),
total: filteredData.length,
})
res.end();
})
.catch(err => {
res.setHeader('Content-Type', 'application/json');
res.json({ succ1ess: false, message: err });
res.end();
});
}
Error error
Update model.ts
import mongoose from "mongoose"
import bcrypt from "bcryptjs"
import { array } from "@hapi/joi"
const shema: any = mongoose.Schema
export interface IUser extends mongoose.Document {
nom: string;
prenom: string;
fullname: string;
telephone: string;
genre: string;
date_naissance: string;
email: string;
password: string;
role: string;
ability: string;
isActive: boolean;
encryptPassword(password: string): Promise<string>;
validatePassword(password: string): Promise<boolean>;
}
const usersShema = new shema({
nom: {
type: String,
required: true,
},
prenom: {
type: String,
required: true,
},
telephone: {
type: String,
required: true,
unique: true,
sparse: true,
},
genre: {
type: String,
required: true,
enum: ['homme', 'femme']
},
date_naissance: {
type: Date,
required: false
},
email: {
type: String,
required: false,
unique: true,
sparse: true,
},
password: {
type: String,
required: true,
min: [6, 'Le mot de passe doit contenir au moins 6 caractères'],
},
role: {
type: String,
required: true,
enum: ['superadmin', 'admin', 'comptable', 'logistique', 'encadreur']
},
ability: {
type: Array,
required: true,
},
isActive: {
type: Boolean,
required: true,
default: true
}
}, { _id: true, timestamps: true })
usersShema.methods.encryptPassword = async (password: string): Promise<string> => {
const salt = await bcrypt.genSalt(10)
return bcrypt.hash(password, salt)
}
usersShema.methods.validatePassword = async function (password: string): Promise<Boolean> {
return await bcrypt.compare(password, this.password)
}
const Users = mongoose.model<IUser>('User', usersShema)
export default Users
route.ts
import { Router } from 'express';
import userController from '../controller/UsersAuth.Controller';
import validationToken from '../libs/verifyToken'
class usersRouter {
router: Router;
constructor() {
this.router = Router();
this.routes();
}
routes() {
this.router.post('/add', userController.AddUser) //Create
this.router.post('/login', userController.Login) //Route login
this.router.get('/profile', validationToken.TokenValidation, userController.profile) //Route profile
this.router.get('/userEmail/:email', userController.GetUser)
this.router.get('/list', userController.GetAllUsers)
}
}
export default new usersRouter().router;
call route
this.app.use("/api/auth", usersRouter)
CodePudding user response:
From the error message, it seems that you are setting the headers after part of the body has been written (explained here: Error: Can't set headers after they are sent to the client).
It would think that the error arises in the catch
block, where you call res.setHeader
. Try to comment out that line and see if the error still occurs.