# Nested validation

To validate an entity, the underlying rules must be followed:

* The entity must be an **object**
* The object must have a **single field**, the <mark style="color:blue;">`id`</mark>
* The <mark style="color:blue;">`id`</mark> must be a **positive integer**

Sounds familiar? We already have a structure that meets these requirements: The <mark style="color:blue;">`IdDto`</mark>. Because of that, we can use it to type the <mark style="color:blue;">`categories`</mark> field inside the DTO.

Apart from that, we just need to indicate that the validation used will be from the <mark style="color:blue;">`IdDto`</mark> itself. We can achieve that with the <mark style="color:blue;">`@ValidateNested()`</mark> decorator. Lastly, as it is not a primitive type, we need to explicitly state the type that is being validated with <mark style="color:blue;">`@Type()`</mark>. With that, we should get the following result:

```typescript
@ArrayNotEmpty()
@ArrayUnique()
@ValidateNested()
@Type(() => IdDto)
readonly categories: IdDto[];
```

As a last improvement, we can create the decorator <mark style="color:blue;">`@IsEntity()`</mark> for this specific validation. Let's do so now in <mark style="color:purple;">common</mark>/<mark style="color:purple;">decorators</mark>/<mark style="color:purple;">is-entity.decorator</mark>. Note that, in this case, we need to also add the validator <mark style="color:blue;">`@IsDefined()`</mark> to enforce validation if the field is not present.

```typescript
/** Checks if the value is an object with only a serial id. */
export const IsEntity = (): PropertyDecorator =>
  applyDecorators(
    IsDefined(),
    ValidateNested(),
    Type(() => IdDto),
  );
```

Now, we can use it in this field and whenever necessary.

However, the <mark style="color:blue;">`@ArrayUnique()`</mark> validator will not work now because we are validating objects, which are compared by reference. Fortunately, we can fix this by passing an **identifier function** to the decorator that states how these objects should be compared. The idDtos should be compared by their ids, so let's create this function in <mark style="color:purple;">common</mark>/<mark style="color:purple;">util</mark>/<mark style="color:purple;">id.util</mark>.

```typescript
export const idDtoIdentifier = (dto: IdDto) => dto.id;
```

And then simply pass this function (<mark style="color:red;">not</mark> call it) to the decorator.

<mark style="color:green;">**Commit**</mark> - Implementing product logic and using nested validation


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kinesis-school-of-programming.gitbook.io/nestjs-unleashed/core-module-backend-development-with-nestjs/remaining-domain/logic/entity-validation/nested-validation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
