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

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

Open
geoidesic opened this issue Nov 18, 2020 · 0 comments
Open

Comments

@geoidesic
Copy link
Collaborator

geoidesic commented Nov 18, 2020

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