Skip to content

Allow mapping to and from nested properties #217

@damienalexandre

Description

@damienalexandre

I wish we could map nested objects back and forth with AutoMapper.

Let's take the example from #14:

class User
{
  public string $email;
}

class Order
{
  public string $reference;
  public User $customer;
}

class OrderDTO
{
  public string $reference;
  public string $customerEmail;
}

$customer = new User();
$customer->email = '[email protected]';
$source = new Order();
$source->reference = 'FAC9123';
$source->customer = $customer;

dump($autoMapper->map($source, OrderDTO::class));

// Will output:
//
// OrderDTO {#14 🔽
//  +reference: "FAC9123"
//  +customerEmail: null
// }

Map from Order to OrderDTO

To map data inside customerEmail, so far the only solution is to use a transformer:

class OrderDTO
{
  public string $reference;
  #[MapFrom(Order::class, transformer: "source.user.email")]
  public string $customerEmail;
}

It's working but it's not very natural, a better DX would be:

class OrderDTO
{
  public string $reference;
  #[MapFrom(Order::class, property: "user.email")]
  public string $customerEmail;
}

Map from OrderDTO to Order

The only way I found is to create a transformer and return a User object. Which is very problematic because sometimes, the User could have other values I don't want to lose.

class Order
{
  public string $reference;
  #[MapFrom(OrderDTO::class, transformer: [self, "mapUser"])
  public User $customer;

  public static function mapUser($val, $source) {
    $user = new User();
    $user->email = $source->customerEmail;
    return $user;
  }
}

A better DX would have been:

class OrderDTO
{
  public string $reference;
  #[MapFrom(Order::class, property: "user.email")]
  #[MapTo(Order::class, property: "user.email")]
  public string $customerEmail;
}

And if "User" is null, throw an exception.
(End-user can use the "if" attribute option to prevent unwanted exceptions).

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions