Skip to content

Instantly share code, notes, and snippets.

@Setitch
Created November 23, 2022 13:09
Show Gist options
  • Save Setitch/29b7b2a0ec9098bbdfda9dc1a37ce594 to your computer and use it in GitHub Desktop.
Save Setitch/29b7b2a0ec9098bbdfda9dc1a37ce594 to your computer and use it in GitHub Desktop.
NestJS - class-valitdator interceptor returning more flattened answers
import { BadRequestException, CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { ValidationError } from 'class-validator';
import { catchError, Observable, throwError } from 'rxjs';
@Injectable()
export class BadRequestInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next
.handle()
.pipe(
catchError(err => {
if (err instanceof BadRequestException) {
const message = ((err.getResponse() as any).message);
if (message instanceof Array) {
const flat: any = this.flattenErrors((message as ValidationError[]).filter(m => m instanceof ValidationError));
return throwError(new BadRequestException(flat));
// return throwError(new BadRequestException(validations.map(v => v)));
}
}
return throwError(err);
}),
);
}
flattenErrors(validations: ValidationError[], previousName: string[] = []) {
const ret: Record<string, any> = {};
// console.log(validations);
validations.forEach((v) => {
if (!ret.hasOwnProperty(v.property)) ret[v.property] = [];
if (Object.values(v.constraints || {}).length !== 0) { // hide empty fields that are parents etc
ret[[...previousName, v.property].join('.')] = Object.values(v.constraints || {});
}
// console.log('o', previousName, [...previousName, v.property].join('.'), Object.values(v.constraints || {}))
if (v.children && v.children.length > 0) {
const r = this.flattenErrors(v.children, [...previousName, v.property]);
for (const prop in r) {
if (!r.hasOwnProperty(prop)) continue;
if (r[prop] instanceof Array && r[prop].length === 0) continue; // hide empty fields that are parents etc
ret[prop] = (ret[prop]) ? [...ret[prop], ...r[prop]] : r[prop];
// console.log('x', prop, ret[prop] );
}
}
if (ret[v.property].length===0) {
delete ret[v.property];
}
}, {} as any);
return ret;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment