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

Array of objects in command #42

Closed
Maikel-Koek opened this issue May 9, 2018 · 9 comments
Closed

Array of objects in command #42

Maikel-Koek opened this issue May 9, 2018 · 9 comments
Assignees
Labels
bug Something isn't working

Comments

@Maikel-Koek
Copy link

Maikel-Koek commented May 9, 2018

Hi @prolic,

We'd like to use an array of objects as data in a command, but it seems that's not possible now, or we're doing something wrong.

We've got this object created:

    data TermPrice = TermPrice {
        int $termNrStart,
        ?int $termCount,
        float $price,
        ?float $specialPrice
    } deriving (FromArray, ToArray);

And we try to use an array of TermPrice's in our command:

...
namespace ReachDigital\Subscription\Model\ProductPlan\Command {
    data SubmitFormGlobalScope = SubmitFormGlobalScope {
        ...
        \ReachDigital\Subscription\Model\ProductPlan\TermPrice[] $termPrices
    } deriving (Command);
...

But this results in the following in our SubmitFormGlobalScope class:

...
    public function termPrices(): array
    {
        return \ReachDigital\Subscription\Model\ProductPlan\TermPrice::fromArray($this->payload['termPrices']);
    }

    public static function with(\ReachDigital\Subscription\Model\ProductPlan\PlanId $planId, \ReachDigital\Subscription\Model\ProductPlan\ProductId $productId, \ReachDigital\Subscription\Model\ProductPlan\Enabled $enabled, \ReachDigital\Subscription\Model\ProductPlan\EnabledOnFrontend $enabledOnFrontend, \ReachDigital\Subscription\Model\ProductPlan\Title $title, \ReachDigital\Subscription\Model\ProductPlan\Description $description, \ReachDigital\Subscription\Model\ProductPlan\Schedule $schedule, \ReachDigital\Subscription\Model\ProductPlan\Interval $interval, array $termPrices): SubmitFormGlobalScope
    {
        return new self([
            ...
            'termPrices' => $termPrices->toArray(),
        ]);
    }
...

The result of termPrices() is not an array, this method should probably loop through $this->payload['termPrices'], and call fromArray on all of those items?

The same goes for the value for termPrices in with() (the toArray() should be called in a loop to call toArray() for all termPrices).

Thanks!

@Maikel-Koek
Copy link
Author

Maikel-Koek commented May 9, 2018

The same goes for these methods (termPrices and with) in our event class, FormWasSubmittedInGlobalScope, created by:

namespace ReachDigital\Subscription\Model\ProductPlan\Event {
    data FormWasSubmittedInGlobalScope = FormWasSubmittedInGlobalScope {
        ...
        \ReachDigital\Subscription\Model\ProductPlan\TermPrice[] $termPrices,
    } deriving (AggregateChanged);
...

@Maikel-Koek
Copy link
Author

It probably needs to look something like this?

namespace ReachDigital\Subscription\Model\ProductPlan\Command;

final class SubmitFormGlobalScope extends \Prooph\Common\Messaging\Command
{
    ...
    public function termPrices(): array
    {
        $result = [];
        foreach ($this->payload['termPrices'] as $termPrice) {
            $result[] = \ReachDigital\Subscription\Model\ProductPlan\TermPrice::fromArray($termPrice);
        }

        return $result;
    }

    public static function with(\ReachDigital\Subscription\Model\ProductPlan\PlanId $planId, \ReachDigital\Subscription\Model\ProductPlan\ProductId $productId, \ReachDigital\Subscription\Model\ProductPlan\Enabled $enabled, \ReachDigital\Subscription\Model\ProductPlan\EnabledOnFrontend $enabledOnFrontend, \ReachDigital\Subscription\Model\ProductPlan\Title $title, \ReachDigital\Subscription\Model\ProductPlan\Description $description, \ReachDigital\Subscription\Model\ProductPlan\Schedule $schedule, \ReachDigital\Subscription\Model\ProductPlan\Interval $interval, array $termPrices): SubmitFormGlobalScope
    {
        $termPricesArray = [];
        foreach ($termPrices as $termPrice) {
            /** @var \ReachDigital\Subscription\Model\ProductPlan\TermPrice $termPrice */
            $termPricesArray[] = $termPrice->toArray();
        }

        return new self([
            'planId' => $planId->toString(),
            'productId' => $productId->toScalar(),
            'enabled' => $enabled->toScalar(),
            'enabledOnFrontend' => $enabledOnFrontend->toScalar(),
            'title' => $title->toString(),
            'description' => $description->toString(),
            'schedule' => $schedule->toArray(),
            'interval' => $interval->toArray(),
            'termPrices' => $termPricesArray,
        ]);
    }
    ...

And for our event:

namespace ReachDigital\Subscription\Model\ProductPlan\Event;

final class FormWasSubmittedInGlobalScope extends \Prooph\EventSourcing\AggregateChanged
{
    ...
    public function termPrices(): array
    {
        if (! isset($this->termPrices)) {
            $termPrices = [];
            foreach ($this->payload['termPrices'] as $termPrice) {
                $termPrices[] = \ReachDigital\Subscription\Model\ProductPlan\TermPrice::fromArray($termPrice);
            }
            $this->termPrices = $termPrices;
        }

        return $this->termPrices;
    }

    public static function with(\ReachDigital\Subscription\Model\ProductPlan\PlanId $planId, \ReachDigital\Subscription\Model\ProductPlan\ProductId $productId, \ReachDigital\Subscription\Model\ProductPlan\Enabled $enabled, \ReachDigital\Subscription\Model\ProductPlan\EnabledOnFrontend $enabledOnFrontend, \ReachDigital\Subscription\Model\ProductPlan\Title $title, \ReachDigital\Subscription\Model\ProductPlan\Description $description, \ReachDigital\Subscription\Model\ProductPlan\Schedule $schedule, \ReachDigital\Subscription\Model\ProductPlan\Interval $interval, array $termPrices): FormWasSubmittedInGlobalScope
    {
        $termPricesArray = [];
        foreach ($termPrices as $termPrice) {
            /** @var \ReachDigital\Subscription\Model\ProductPlan\TermPrice $termPrice */
            $termPricesArray[] = $termPrice->toArray();
        }

        return new self($planId->toString(), [
            'productId' => $productId->toScalar(),
            'enabled' => $enabled->toScalar(),
            'enabledOnFrontend' => $enabledOnFrontend->toScalar(),
            'title' => $title->toString(),
            'description' => $description->toString(),
            'schedule' => $schedule->toArray(),
            'interval' => $interval->toArray(),
            'termPrices' => $termPricesArray,
        ]);
    }
    ...

@prolic prolic added the bug Something isn't working label May 10, 2018
@prolic prolic self-assigned this May 10, 2018
@Maikel-Koek
Copy link
Author

Hi @prolic, not to be rude, but when do you think you will start working on this issues?

@prolic
Copy link
Owner

prolic commented May 14, 2018

Just checked with current master branch and I generated this:

<?php

// this file is auto-generated by prolic/fpp
// don't edit this file manually

declare(strict_types=1);

namespace Foo;

final class SubmitFormGlobalScope extends \Prooph\Common\Messaging\Command
{
    use \Prooph\Common\Messaging\PayloadTrait;

    protected $messageName = 'Foo\SubmitFormGlobalScope';

    public function termPrices(): array
    {
        $__returnValue = [];

        foreach ($this->payload['termPrices'] as $__value) {
            $__returnValue[] = TermPrice::fromArray($__value);
        }

        return $__returnValue;
    }

    public static function with(TermPrice ...$termPrices): SubmitFormGlobalScope
    {
        $__array_termPrices = [];

        foreach ($termPrices as $__value) {
            $__array_termPrices[] = $__value->toArray();
        }

        return new self([
            'termPrices' => $__array_termPrices,
        ]);
    }

    protected function setPayload(array $payload): void
    {
        if (! isset($payload['termPrices']) || ! is_array($payload['termPrices'])) {
            throw new \InvalidArgumentException("Key 'termPrices' is missing in payload or is not an array");
        }

        foreach ($payload['termPrices'] as $__value) {
            if (! is_array($__value)) {
                throw new \InvalidArgumentException("Key 'termPrices' is not an array of arrays in payload");
            }
        }

        $this->payload = $payload;
    }
}

which looks good for me, maybe I am missing something?

@Maikel-Koek
Copy link
Author

That does look good indeed, I'll try and check if I'm fully up-to-date, will let you know.

@Maikel-Koek
Copy link
Author

My bad, it's working, I was on 637ffc3!

@prolic
Copy link
Owner

prolic commented May 14, 2018

👍

@Maikel-Koek
Copy link
Author

@prolic Found a little bug;

In my event (FormWasSubmittedInGlobalScope):

    public function termPrices(): array
    {
        $__returnValue = [];

        foreach ($this->payload['termPrices'] as $__value) {
            $__returnValue = \ReachDigital\Subscription\Model\ProductPlan\TermPrice::fromArray($__value);
        }

        return $__returnValue;
    }

In the foreach loop, the $__returnValue = should be $__returnValue[] =.

@prolic
Copy link
Owner

prolic commented May 15, 2018

see list_nullable branch/ PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants