0

I try to create a REST resource. I used EntityResource as base. I would like to return my fields in html. Here is a exemple of my code :

public function get($id) {
    if (!$this->currentUser->hasPermission('access content')) {
      throw new AccessDeniedHttpException();
    }

    $entity = \Drupal::entityTypeManager()->getStorage('node')->load($id);
    $entity_access = $entity->access('view', NULL, TRUE);
    if (!$entity_access->isAllowed()) {
      throw new AccessDeniedHttpException($entity_access->getReason() ? : $this->generateFallbackAccessDeniedMessage($entity, 'view'));
    }

    $result = array();
    $other_entity_dependency = array();
    if ($entity instanceof FieldableEntityInterface) {
      $fields = array();
      $contentType = $entity->bundle();
      if (isset($contentType) && !empty($contentType)) {
        foreach (\Drupal::entityManager()->getFieldDefinitions('node', $contentType) as $field_name => $field_definition) {
          if (!empty($field_definition->getTargetBundle())) {
            $fields[] = $field_name;
          }
        }
      }
      foreach ($fields as $field_name) {
        $field = $entity->$field_name;
        $field_access = $field->access('view', NULL, TRUE);
        if ($field_access->isAllowed()) {
           $value = \Drupal::service('renderer')->render($field->view())
           $result[$field_name]['value'] = $value;
            $result[$field_name]['label'] = $field->getFieldDefinition()->getLabel();

        }
      }
    }


    $response = new ResourceResponse($result, Response::HTTP_OK);
    $response->addCacheableDependency($entity);
    $response->addCacheableDependency($entity_access);

      return $response;
  }

The problem is that when I use a render function, I have this error :

The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early. Returned object class: Drupal\rest\ResourceResponse.

I haven't this issue when I use $field->value instead of \Drupal::service('renderer')->render($field->view()), but I would like to have the html render of fields, for file or image too (these types of fields are empty when I use $field->value).

How can I solve this problem ?

3
  • Don't render arrays get rendered anyway? Can't you just use $value = $field->view() and be done with it?
    – Clive
    Commented Jan 31, 2018 at 10:35
  • When use only $value = $field->view() I get this error : Uncaught PHP Exception Symfony\\Component\\Serializer\\Exception\\UnexpectedValueException: "Could not normalize object of type Drupal\\Core\\Url, no supporting normalizer found."
    – Lucuhb
    Commented Jan 31, 2018 at 10:47
  • Actually I guess that makes sense, there's no context available - how would it know what theme to use, for example?
    – Clive
    Commented Jan 31, 2018 at 12:02

1 Answer 1

0

The problem is, that render() produces metadata which leaks to the outside of the controller. You can try renderPlain() if you don't care about the metadata or see this question how to provide your own render context to catch the metadata and add it to the response:

How to get cache metadata from nested render array when returning response?

1
  • Thanks, I use the exemple that you give and now all metadata are catched. : the error is gone away.
    – Lucuhb
    Commented Feb 6, 2018 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.