Skip to content

_convertJsonApiDocumentArray is failing when trying to set empty array. #147

Open
@geoidesic

Description

@geoidesic

package.json:

        "friendsofcake/crud-json-api": "^1.0.1",`

As per: https://jsonapi.org/format/#crud-updating-to-many-relationships
E.g. URL:
PATCH http://{{domain}}/api/enquiries/2/relationships/administratives

{
    "data": []
}

Error:


2020-11-18 17:32:39 Error: [TypeError] Return value of App\Listener\JsonApiListener::_convertJsonApiDocumentArray() must be of the type array, object returned in /Users/noeldacosta/repo/mnr-be/src/Listener/JsonApiListener.php on line 80
Stack Trace:
- /Users/me/project/vendor/friendsofcake/crud-json-api/src/Listener/JsonApiListener.php:1271
- /Users/me/project/vendor/friendsofcake/crud-json-api/src/Listener/JsonApiListener.php:129
- /Users/me/project/vendor/cakephp/cakephp/src/Event/EventManager.php:309
- /Users/me/project/vendor/cakephp/cakephp/src/Event/EventManager.php:286
- /Users/me/project/vendor/friendsofcake/crud/src/Controller/Component/CrudComponent.php:550
- /Users/me/project/vendor/friendsofcake/crud/src/Controller/Component/CrudComponent.php:242
- /Users/me/project/vendor/friendsofcake/crud/src/Controller/ControllerTrait.php:68
- /Users/me/project/vendor/cakephp/cakephp/src/Controller/ControllerFactory.php:79
- /Users/me/project/vendor/cakephp/cakephp/src/Http/BaseApplication.php:251
- /Users/me/project/vendor/cakephp/cakephp/src/Http/Runner.php:77
- /Users/me/project/vendor/cakephp/cakephp/src/Http/Runner.php:77
- /Users/me/project/vendor/cakephp/cakephp/src/Http/Middleware/BodyParserMiddleware.php:174
- /Users/me/project/vendor/cakephp/cakephp/src/Http/Runner.php:73
- /Users/me/project/plugins/Cors/src/Middleware/CorsMiddleware.php:45
- /Users/me/project/vendor/cakephp/cakephp/src/Http/Runner.php:73
- /Users/me/project/vendor/cakephp/cakephp/src/Http/Runner.php:58
- /Users/me/project/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php:172
- /Users/me/project/vendor/cakephp/cakephp/src/Http/Runner.php:73
- /Users/me/project/vendor/cakephp/cakephp/src/Routing/Middleware/AssetMiddleware.php:68
- /Users/me/project/vendor/cakephp/cakephp/src/Http/Runner.php:73
- /Users/me/project/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php:121
- /Users/me/project/vendor/cakephp/cakephp/src/Http/Runner.php:73
- /Users/me/project/vendor/cakephp/cakephp/src/Http/Runner.php:58
- /Users/me/project/vendor/cakephp/cakephp/src/Http/Server.php:90
- /Users/me/project/webroot/index.php:40

This may be because of my route bodyParser:

function jsonIterator(&$parsed)
{
    if (is_array($parsed)) {
        foreach ($parsed as $key => &$value) {
            if (is_array($value)) {
                if (empty($value)) {
                    $parsed[$key] = new stdClass();
                } else {
                    jsonIterator($value);
                }
            }
        }
    }
}

Router::prefix('api', function (RouteBuilder $routes) {
     $bodyParser->addParser(['application/vnd.api+json'], function ($body) {
        if (!empty($body)) {
            $parsed = json_decode($body, true);
            jsonIterator($parsed);
            return $parsed;
        }
        return [];
     ...

This body parser is necessary if you are using and columns in the database of type JSON because otherwise empty objects will be converted to empty arrays (because json_ecode / decode can't tell the difference between empty associative and empty indexed arrays... you can set it to covert empty arrays to arrays or to objects but if you have both empty associate and indexed arrays then you one of them is going to cause errors.

For this reason I would suggest a change to line JsonApiListener:75:

// handle relationships URLd
        if ($this->_checkIsRelationshipsRequest()) {
            // @customised: cast as array to avoid any problems with parsing issues when converting between JavaScript and PHP (q.v. comments on routes.php::jsonIterator)
            $result = (array)$document['data'];    //<--- Cast this to array to avoid these parsing problems.
        }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions