core icon indicating copy to clipboard operation
core copied to clipboard

[Graphql] Gedmo Tree error Expected data to be an array

Open BernardA opened this issue 6 years ago • 5 comments

I am new to API platform. I got a few "regular" entities working with API Platform, but struggling with Gedmo Tree type nested with its self-referencing properties.

This is the query I am trying to run:

  {
categories{
        edges{
           node{
              id
              title
              root{
                 id
                 title
              }
              parent{
                 id
                title
             }
        }
      }
    }
   }

It throws error :

"Expected data to be an array"

I attempted to setup ApiSubresource on the self referencing properties, but that did not change the error.

Here is most of App\Entity\Category

  /**
   * @Gedmo\Tree(type="nested")
   * @ORM\Entity(repositoryClass="App\Repository\CategoryRepository")
   * @ApiResource(
   *     itemOperations={
   *          "get"={
   *             "normalization_context"={
   *                 "groups"={"get-cats"}
   *             }
   *          },
   *          "put"={
   *              "access_control"="is_granted('ROLE_ADMIN')"
   *          }
   *      },
   *      collectionOperations={
   *          "get",
   *          "post"={
   *              "access_control"="is_granted('ROLE_ADMIN')"
   *          }
   *      },
   *      denormalizationContext={
   *          "groups"={"post"}
   *      }
   * )
   * @ORM\Table(
   *      name="categories",
   *      uniqueConstraints={@ORM\UniqueConstraint(name="partitle", columns={"parent_id", "title"})}
   * )
   * @UniqueEntity(
   *      fields={"title","parent"},
   *      errorPath="title",
   *      repositoryMethod="checkDuplicateTitle",
   *      message="Sub-category already exists for this category "
  * )
  */

 class Category
{

/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue
 * @Groups({"get", "get-cats"})
 */
private $id;

/**
 * @ORM\Column(type="string", length=190)
 * @Groups({"get", "get-cats"})
 */
private $title;

/**
 * @Gedmo\TreeLeft
 * @ORM\Column(name="lft", type="integer")
 */
private $lft;

/**
 * @Gedmo\TreeLevel
 * @ORM\Column(name="lvl", type="integer")
 */
private $lvl;

/**
 * @Gedmo\TreeRight
 * @ORM\Column(name="rgt", type="integer")
 */
private $rgt;

/**
 * @Gedmo\TreeRoot
 * @ORM\ManyToOne(targetEntity="Category")
 * @ORM\JoinColumn(referencedColumnName="id", onDelete="CASCADE")
 * @ApiSubresource()
 * @Groups({"get", "get-cats"})
 */
private $root;

/**
 * @Gedmo\TreeParent
 * @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
 * @ORM\JoinColumn(referencedColumnName="id", onDelete="CASCADE")
 * @ApiSubresource()
 * @Groups({"get", "get-cats"})
 */
private $parent;

/**
 * @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
 * @ORM\OrderBy({"lft" = "ASC"})
 * @ApiSubresource()
 * @Groups({"get-cats"})
 */
private $children;

BernardA avatar Sep 06 '19 07:09 BernardA

On further investigation I noticed that the issue seems to be related to the root property.

This query, without root, works:

  {
categories{
      edges{
        node{
          id
          title
          parent{
            id
            title
          }
        }
      }
    }

Also for individual categories it works even with root:

     category(id:"/api/categories/15"){
         id
         _id
        title
         parent{
             id
             title
          }
          root{
              id
              title
          }
       }

So it's related to GET at the collection level.

BernardA avatar Sep 06 '19 08:09 BernardA

Posting the error from profiler. It seems that the serializer was expecting $data to be an array and instead it's getting an instance of category:

   {
    "errors": [
     {
       "debugMessage": "Expected data to be an array",
       "message": "Internal server error",
       "extensions": {
         "category": "internal"
       },
       "locations": [
         {
           "line": 35,
           "column": 9
         }
       ],
      "path": [
         "withCustomArgsMutationCategory"
       ],
       "trace": [
         {
           "file": "/Users/bernardo/Sites/quiamo-api/vendor/symfony/serializer/Serializer.php",
           "line": 152,
           "call": "ApiPlatform\\Core\\GraphQl\\Serializer\\ItemNormalizer::normalize(instance of App\\Entity\\Category, 'graphql', array(10))"
         },

BernardA avatar Apr 08 '20 19:04 BernardA

A root element in Gedmo-Tree is created as below:

  $food = new Category();
  $food->setTitle('Food');

This is also what happens if one uses the createCategory mutation in GraphQl.

That will generate an entry in the category table like so:

  id : 3385
  root: 3385 // same as id
  parent: NULL
  title: Food

Now, if I go to PHPMyAdmin and manually set root to NULL, I will be able to execute the Graphql query on root without throwing the error above. I will have that item in the category table as:

   id: 3385
   root: NULL
   parent: NULL
   title: Food

I stressed manually, as the Gedmo-Tree Category entity does not have a setRoot() method. The root is set automatically by Gedmo.

This is a hack that solves the issue with this error. So far I have not run into any issues caused by the hack as such. I was able to query categories with GraphQl normally, even when root is also retrieved.

I did not test with the specific methods provided by Gedmo-Tree though.

So, whenever an user of this app creates a root node I will have to go manually and nullify the root field so that the app does not crash when attempting to retrieve categories. That's not fantastic.

In conclusion, it would seem that API-Platform has an issue dealing with Gedmo-Trees set up.

BernardA avatar Apr 09 '20 07:04 BernardA

Well, I stand corrected. Just found that it will not correctly create a child to root when hacked as above. It will set root as null when it should be the root id and all else will be queried incorrectly afterwards.

BernardA avatar Apr 09 '20 13:04 BernardA

This issue appears to me too

  • I have an entity with self-relation
  • The entity has no Gedmo-Tree set up,
  • Expected data to be an array exception throws when i fetch an item that has a parent already related as another item's parent.

aelfannir avatar Mar 23 '22 12:03 aelfannir

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Nov 04 '22 21:11 stale[bot]

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Jan 03 '23 23:01 stale[bot]