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

Allow mapping to and from nested properties #217

Open
damienalexandre opened this issue Jan 17, 2025 · 0 comments
Open

Allow mapping to and from nested properties #217

damienalexandre opened this issue Jan 17, 2025 · 0 comments

Comments

@damienalexandre
Copy link
Member

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant