LogicException: 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. in Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext() (line 154 of /srv/bindings/8c5ccf24ccc9492bb85469725da608ea/code/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php).
I am facing this issue when i try to access REST endpoint through ajax get request. Important thing, when i was logged-in then every works find but when i am not logged it it through above exception.
Here is my code
namespace Drupal\one_rest_api\Plugin\rest\resource; use Drupal\file\Entity\File; use Drupal\image\Entity\ImageStyle; use Drupal\media_entity\Entity\Media; use Drupal\node\Entity\Node; use Drupal\rest\Plugin\ResourceBase; use Drupal\rest\ResourceResponse; use Drupal\Core\Session\AccountProxyInterface; use Drupal\taxonomy\Entity\Term; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\HttpException; /** * Provides article resource endpoint * * @RestResource( * id = "one_article_resource", * label = @Translation("One Article Resource"), * uri_paths = { * "canonical" = "/api/one/v1/articles" * } * ) */ class ArticleResource extends ResourceBase { /** * A current user instance. * * @var \Drupal\Core\Session\AccountProxyInterface */ protected $ currentUser; /** * Constructs a Drupal\rest\Plugin\ResourceBase object. * * @param array $ configuration * A configuration array containing information about the plugin instance. * @param string $ plugin_id * The plugin_id for the plugin instance. * @param mixed $ plugin_definition * The plugin implementation definition. * @param array $ serializer_formats * The available serialization formats. * @param \Psr\Log\LoggerInterface $ logger * A logger instance. * @param \Drupal\Core\Session\AccountProxyInterface $ current_user * A current user instance. */ public function __construct( array $ configuration, $ plugin_id, $ plugin_definition, array $ serializer_formats, LoggerInterface $ logger, AccountProxyInterface $ current_user) { parent::__construct($ configuration, $ plugin_id, $ plugin_definition, $ serializer_formats, $ logger); $ this->currentUser = $ current_user; } /** * {@inheritdoc} */ public static function create(ContainerInterface $ container, array $ configuration, $ plugin_id, $ plugin_definition) { return new static( $ configuration, $ plugin_id, $ plugin_definition, $ container->getParameter('serializer.formats'), $ container->get('logger.factory')->get('one_rest'), $ container->get('current_user') ); } /** * Responds to GET requests. * * Returns a list of bundles for specified entity. * * @throws \Symfony\Component\HttpKernel\Exception\HttpException * Throws exception expected. */ public function get() { global $ base_url; $ response_result = []; $ response_code = 200; // You must to implement the logic of your REST Resource here. // Use current user after pass authentication to validate access. if (!$ this->currentUser->hasPermission('access content')) { throw new AccessDeniedHttpException(); } $ entities = \Drupal::entityQuery('node') ->condition('status', 1) ->condition('type', 'article') ->condition('langcode','en') ->notExists('field_f1') ->sort('created', 'DESC') ->range(0, 20) ->execute(); if(!empty($ entities)){ foreach ($ entities as $ node_id) { $ node = Node::load($ node_id); if(is_object($ node)){ $ image_url = ''; $ image_target = $ node->get('field_image')->target_id; if(!empty($ image_target)){ $ media = Media::load($ image_target); if(is_object($ media)){ $ image = File::load($ media->get('field_image')->target_id); $ image_url = ImageStyle::load('rest_api')->buildUrl($ image->getFileUri()); } } $ output_tags = []; $ tags = $ node->get('field_tags')->getValue(); if(!empty($ tags)){ foreach($ tags as $ key => $ tag){ $ term = Term::load($ tag['target_id']); $ output_tags[] = $ term->get('name')->value; } } $ result = [ "nid" => $ node->id(), "base_url" => $ base_url, "title" => $ node->getTitle(), "field_image" => $ image_url, "field_tags" => $ output_tags ]; $ response_result[] = $ result; } } } if(!empty($ response_result)) { $ headers = [ 'Access-Control-Allow-Origin' => '*', 'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PATCH, DELETE', 'Access-Control-Allow-Headers' => 'Authorization' ]; $ response = new ResourceResponse($ response_result, $ response_code, $ headers); return $ response; } throw new HttpException(t("Empty Response")); } }
And Below is my typescript code
load(){ if(this.data){ return Promise.resolve(this.data); } return new Promise(resolve => { this.http.get('https://example.com/api/one/v1/articles?_format=json') .subscribe(data => { this.data = data; resolve(this.data); },err => { console.log(err); }); }); }
I didn’t understand what i am missing in drupal code