I want to serialize a controller response but it's not working with array
UserSerialization
import { Role } from '@prisma/client';
import { Exclude, Expose } from 'class-transformer';
export const GROUP_USER_ME = 'GROUP_USER_ME';
@Exclude()
export class UserSerialization {
@Expose({ groups: [GROUP_USER_ME] })
id: string;
@Expose({ groups: [GROUP_USER_ME] })
email: string;
@Expose({ groups: [GROUP_USER_ME] })
name: string;
@Expose({ groups: [GROUP_USER_ME] })
createdAt: Date;
@Expose({ groups: [GROUP_USER_ME] })
updatedAt: Date;
@Expose({ groups: [GROUP_USER_ME] })
role: Role;
constructor(partial: Partial<UserSerialization>) {
Object.assign(this, partial);
}
}
Controller
import { Role } from '@prisma/client';
import {
GROUP_USER_ME,
UserSerialization,
} from './serialization/user.serialization';
import {
ClassSerializerInterceptor,
Controller,
Get,
HttpCode,
HttpStatus,
Post,
SerializeOptions,
Session,
UnauthorizedException,
UseInterceptors,
} from '@nestjs/common';
import {
SessionContainer,
} from 'supertokens-node/recipe/session';
import { AuthService } from './auth.service';
@Controller('auth')
@UseInterceptors(ClassSerializerInterceptor)
export class AuthController {
constructor(private readonly authService: AuthService) {}
@Get('/')
@SerializeOptions({ groups: [GROUP_USER_ME] })
async me(@Session() session: SessionContainer): Promise<UserSerialization> {
const userID = session.getUserId();
const users = await this.authService.allUsers(userID);
if (!users) {
await session.revokeSession();
throw new UnauthorizedException();
}
return new UserSerialization(users);
}
}
the porblem occurs on this new UserSerialization(users);
, when I pass array I get this error Type 'User[]' has no properties in common with type 'Partial<UserSerialization>'
, however it works when I pass single user. So how I should make this work with array and without array?
CodePudding user response:
Would it make sense to you if you had the following?
export function square(num: number): number {
return num * num;
}
const numbers = [1, 3, 5];
console.log(square(numbers))
It doesn't does it?
You've told Typescript you expect to pass a single Partial<UserSerialization>
to the UserSerialization
constructor, but in your code you try to pass an array of User
(User[]
). Typescript is properly telling you "Hey, that's an array, this method only takes in a single object". So what do you do? You need to use a map
to create a array of UserSerialization
(UserSerialization[]
) as the return of your method
@Get('/')
@SerializeOptions({ groups: [GROUP_USER_ME] })
async me(@Session() session: SessionContainer): Promise<UserSerialization[]> {
const userID = session.getUserId();
const users = await this.authService.allUsers(userID);
if (!users) {
await session.revokeSession();
throw new UnauthorizedException();
}
return users.map(user => new UserSerialization(user));
}
}
If you are expecting to return a single object, then you need to update the return of your service code