Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include @IsOptional values to the body if they are missing with default value #1632

Closed
AndonMitev opened this issue Oct 12, 2023 · 3 comments
Labels
type: question Questions about the usage of the library.

Comments

@AndonMitev
Copy link

AndonMitev commented Oct 12, 2023

Having following DTO:

export class UserLoginRequestDto {
  @IsOptional()
  email: string;

  @IsOptional()
  password: string;
}

and passing outside body: { email: 'test@gmail.com' } , how to create pipe that will check keys which are missing from the dto and assign to them null so after pipe, body becomes:

body: { email: 'test@gmail.com', password: null }

import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';
import { instanceToPlain, plainToClass } from 'class-transformer';

@Injectable()
export class AugmentOptionalPropertiesPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
const { metatype } = metadata;

if (!metatype) {
  return value;
}

// Convert the incoming value to an instance of the DTO
const dtoInstance = plainToClass(metatype, value);
// Convert the DTO instance back to a plain object
const plainObj = instanceToPlain(dtoInstance, { excludeExtraneousValues: false });

// Assign null to undefined properties
for (const prop in plainObj) {
  if (plainObj[prop] === undefined) {
    plainObj[prop] = null;
  }
}

console.log(Object.entries(metatype.prototype));
Object.entries(metatype.prototype).forEach(([key, defaultValue]) => {
  if (dtoInstance[key] === undefined) {
    dtoInstance[key] = null; // Or use 'defaultValue' if you want a specific default value
  }
});

console.log('plainObj', plainObj);
return plainObj;

}
}

However i'm not able to find easy way to iterate over the keys from the DTO model it self, any ideas

@AndonMitev AndonMitev added the type: question Questions about the usage of the library. label Oct 12, 2023
@diffy0712
Copy link

The IsOptional decorator is not a class-transformer decorator so it will not have affect on the transformer.

I think you can use a custom Transformer to make this behavior using class-transformer:

export class UserLoginRequestDto {
  @Expose()
  @Transform(({value}) => value ?? null )
  email?: string;

  @Expose()
  @Transform(({value}) => value ?? null )
  password?: string;
}

I have added the ?: to the types so typescript will know that it might be undefined (this is just a type, will not have affect, but in strict ts it will work nicely)
Also I have added a custom transformer to return null on undefined. Since the Transform only run when Exposed explicitly I have added the @Expose as well. (you can create your very on @NullOnPlainTransform decorator if you want to make it read nicely)

This is a way you can make this work using class-transformer.

The thing you tried to implement I think can work a bit better since, you do not have to add anything on your existing DTO-s.
Just a note that you could use Object.getOwnPropertyNames as well to get the available keys and if it does not exists on your plain you can just set it to null.

This is a bit old question, so I assume you were already be able to make it work.

@diffy0712
Copy link

Closing as answered. If you have any questions left feel free to comment on this issue.

Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: question Questions about the usage of the library.
Development

No branches or pull requests

2 participants