automapper icon indicating copy to clipboard operation
automapper copied to clipboard

Impossible to map to a nested collection of Target-Classes?

Open FranzBruckner opened this issue 3 months ago • 1 comments

I am struggling now since hours, maybe I am doing something wrong, maybe there is a bug or it's just not possible.

Basically I have a collection in the src and the target-object. The elements are all of the same type (typehinted, docblocks, everything there). But I am no capable to map the elements from the source-objects collection to the type of the target-objects collection. The elements of the collection are mapped but not to the target type :-(

Again, please apologize if I missed that somewhere in the documentation.

Call

assert($searchResult instanceof LegacyPaginatedData);
$response = $autoMapper->map($searchResult, UserSubusersResponse::class, [
      'groups' => ['user:subuser'],
  ]);

Result

UserSubusersResponse::$currentPage is fine.
UserSubusersResponse::$data is a collection of UserEntities (instead of a collection of UserSubuserResources)

Target-Objects

// Target (Root)
#[Groups(['user:subuser'])]
final class UserSubusersResponse
{
    #[MapFrom(LegacyPaginatedData::class)]
    public int $currentPage;

    /** @var iterable<UserSubuserResource> */
    #[MapFrom(LegacyPaginatedData::class)]
    public iterable $data = [];
}


#[Groups(['user:subuser'])]
final class UserSubuserResource
{
    #[MapFrom(User::class, property: 'uid')]
    public int $uid;

    #[MapFrom(User::class)]
    public string $email;
}

Source-Objects

/**
 * @template T
 */
#[Groups(['user:subuser'])]
final readonly class LegacyPaginatedData
{
    /**
     * @param iterable<T> $data
     */
    private function __construct(
        /** @var iterable<T> */
        public array $data,
        public int $currentPage,
        public int $currentPageSize,
        public int $pageCount,
        public int $totalCount,
        public string $orderBy = 'timeCreated',
        public string $orderDirection = 'ASC',
    ) {
    }
}


#[Groups(['user:subuser'])]
class UserEntity {
  // protected properties and public getters
}

FranzBruckner avatar Sep 19 '25 14:09 FranzBruckner

You should take a look at what the mapper is resolving for the metadata (if you use symfony, there is a profiler / command to debug this, otherwise you can take a look at the generated code)

I suspect it does not know the source type of the collection so he map to nothing (he assume it's the same type by default if he doesn't know)

joelwurtz avatar Sep 22 '25 09:09 joelwurtz

Closing this, reopen it if you have more details

joelwurtz avatar Nov 30 '25 13:11 joelwurtz