# Fetching products with filenames

Now, we should fetch the products together with their images' filenames. Unfortunately, this <mark style="color:red;">cannot</mark> be achieved with the <mark style="color:blue;">`@Expose()`</mark> decorator, as the **class-transformer** library does not support asynchronous transformations. However, there is an event listener that can be used: <mark style="color:blue;">`afterLoad()`</mark>. With a suggestive name, it executes after an entity is loaded. This way, we can perform this process in the file <mark style="color:purple;">products</mark>/<mark style="color:purple;">subscribers</mark>/<mark style="color:purple;">products.subscriber</mark>. We should just remember to add it to the <mark style="color:blue;">`providers`</mark> in the <mark style="color:blue;">`ProductsModule`</mark>. Below, we can see its basic template.

```typescript
@EventSubscriber()
export class ProductsSubscriber implements EntitySubscriberInterface<Product> {
  constructor(private readonly dataSource: DataSource) {
    dataSource.subscribers.push(this);
  }

  listenTo() {
    return Product;
  }
}
```

Here, we'll first create a private method that receives the <mark style="color:blue;">`id`</mark> of a <mark style="color:blue;">`product`</mark> and returns the <mark style="color:blue;">`filenames`</mark> of its <mark style="color:blue;">`images`</mark>, if the respective directory exists.

```typescript
private async getImagesFilenames(id: number) {
  const { BASE, IMAGES } = FilePath.Products;
  const path = join(BASE, id.toString(), IMAGES);

  if (!(await pathExists(join(BASE_PATH, path)))) return;

  return this.storageService.getDirFilenames(path);
}
```

And above it, we can then use the <mark style="color:blue;">`afterLoad()`</mark> event listener to create a field for these <mark style="color:blue;">`filenames`</mark> when fetching <mark style="color:blue;">`products`</mark>. This may not be the most ideal way, but as the <mark style="color:blue;">`@Expose()`</mark> decorator has the aforementioned flaw, this may be a viable alternative.

```typescript
async afterLoad(entity: Product) {
  const product = entity;

  const imagesFilenames = await this.getImagesFilenames(product.id);
  product[this.IMAGES_FILENAMES_KEY] = imagesFilenames;
}

private readonly IMAGES_FILENAMES_KEY = 'imagesFilenames';
```

<mark style="color:green;">**Commit**</mark> - Retrieving products with images filenames

With this, the last remaining step is to make the images in the upload folder become directly available just by accessing their paths.
