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

DealsTimeline mapping error: JsonMapper::map requires first argument to be an object, array given. #52

Closed
BradGriffith opened this issue Oct 6, 2021 · 3 comments

Comments

@BradGriffith
Copy link

InvalidArgumentException
JsonMapper::map() requires first argument to be an object, array given.
in vendor/apimatic/jsonmapper/src/JsonMapper.php:103

image

It looks like the getDealsTimeline API response returns an object with the data member as an array for like this:

object(stdClass)#2247 (2) {
    ["success"]=>
    bool(true)
    ["data"]=>
    array(12) {
      [0]=>
      object(stdClass)#2244 (4) {
        ["period_start"]=>
        string(19) "2021-08-01 00:00:00"
        ["period_end"]=>
        string(19) "2021-08-31 23:59:59"
        ["deals"]=>
        array(9) {
          [0]=>
          object(stdClass)#2246 (69) {
            ["id"]=>
            int(1193)
            ["creator_user_id"]=>
            int(149104)
            ["user_id"]=>
            ...

When jsonmapper tries to map this response in pipedrive/pipedrive/src/Controllers/DealsController.php:459 the data ends up being recognized as an object of type \Pipedrive\Models\Data25 rather than as an array. But in apimapper/jsonmapper/src/JsonMapper.php:103 an InvalidArgumentException is thrown because $json that is passed in is an array rather than an object.

Ultimately, I think JsonMapper should be calling mapArray or mapClassArray around JsonMapper.php:247 but it is instead trying to call map which only works with an object.

I wish I could have determined the root cause here to provide a merge request to fix this, but the best I could come up with is to skip using JsonMapper and to instead just return the object that comes back from the API. This looks like:

--- vendor/pipedrive/pipedrive/src/Controllers/DealsController.php.old
+++ vendor/pipedrive/pipedrive/src/Controllers/DealsController.php
@@ -454,7 +454,7 @@ class DealsController extends BaseContro
 
         $mapper = $this->getJsonMapper();
 
-        return $mapper->mapClass($response->body, 'Pipedrive\\Models\\GetDealsTimeline');
+        return $response->body;
     }

That solution neglects whatever value JsonMapper has.

Thanks for your help troubleshooting and fixing this issue!

@BradGriffith
Copy link
Author

Note the above is for package version 1.01. I get similar errors in 3.2 but the line numbers are different.

image

InvalidArgumentException
JsonMapper::map() requires first argument to be an object, array given.

apimatic/jsonmapper/src/JsonMapper.php:103
apimatic/jsonmapper/src/JsonMapper.php:270
apimatic/jsonmapper/src/JsonMapper.php:322
vendor/pipedrive/pipedrive/src/Controllers/DealsController.php:396

@BradGriffith
Copy link
Author

I believe I've found a solution for this that's a very simple change in the GetDealsTimeline model to indicate that the data is an array of Data25 objects, not just a single Data25 object.

--- a/src/Models/GetDealsTimeline.php
+++ b/src/Models/GetDealsTimeline.php
@@ -23,14 +23,14 @@ class GetDealsTimeline implements JsonSerializable
     /**
      * Open and won Deals grouped into periods by defined interval, amount and date-type dealField
      * (field_key)
-     * @var \Pipedrive\Models\Data25|null $data public property
+     * @var \Pipedrive\Models\Data25[]|null $data public property
      */
     public $data;
 
     /**
      * Constructor to set initial or default values of member properties
      * @param bool   $success Initialization value for $this->success
-     * @param Data25 $data    Initialization value for $this->data
+     * @param Data25[] $data    Initialization value for $this->data
      */
     public function __construct()
     {

I opened a pull request for this change (see above)

@SpaceOven
Copy link
Contributor

SpaceOven commented May 5, 2023

Hi!
Thanks for the solution! I'm checking open PRs, one of them was related to this issue. The issue was solved on this commit:
7734d20

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

Successfully merging a pull request may close this issue.

2 participants