0

I am new on Drupal 8 , so i have created a service class which return a list of data, 'articles' (node entities), and I call this service class inside a controller, but no data showing up :

My getArticles() method inside my service:

  public function getArticles(){
    $storage = \Drupal::service('entity_type.manager')->getStorage('node');
    $my_entity_ids = $storage->getQuery()
      ->condition('type', 'article')
      ->condition('status', 1)
      ->execute();
    $my_entities = $storage->loadMultiple($my_entity_ids);
    return $my_entities;
  }

My controller:

public function myPage() {
    $data = \Drupal::service('mymodule.service');
    $dataService = $data->getArticles();
    return $dataService;
  }

My result is a blank white page when I view the path routed to my controller, but I see the following message in my error log:

Recoverable fatal error : Object of class Drupal\node\Entity\Node could not be converted to string dans Drupal\Component\Utility\Xss::filter()'' -----"Warning : strlen() expects parameter 1 to be string, array given dans Drupal\Component\Utility\Unicode::validateUtf8()

Can anyone tell me please why i can't get the articles?

  • 2
    You have the articles. They are objects with data. You haven't specified how they should be displayed. Your myPage() method needs to return a render array. What are you trying to display from the articles? – sonfd Jun 27 at 23:40
  • Let’s say the title of the articles – David montera Jun 28 at 0:09
  • For example i want to display the title of articles – David montera Jun 28 at 0:16
3

Controllers need to return a render array. Let's imagine you process your articles for render in a new method renderMyPage() which you call from myPage() and pass your array of article objects.

If you're displaying multiple fields from the articles, you're best off building and configuring a view mode and then getting the view mode render array as described in this answer.

function renderMyPage($articleObjects) {
  $view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');

  $articles = [];
  foreach ($articleObjects as $article) {
    $articles[] = $view_builder->view($article, 'my_view_mode_machine_name');
  }

  return $articles;
}

If you want to render a single field from your article, you can get the render array for a field as described in this answer.

function renderMyPage($articleObjects) {
  $articles = [];
  foreach ($articleObjects as $article) {
    // You can pass a view_mode machine name or
    // an array of field configurations to view().
    $articles[] = $article->title->view();
  }

  return $articles;
}

Alternatively you can build your own render array, say to render the title as an h2.

function renderMyPage($articleObjects) {
  $articles = [];
  foreach ($articleObjects as $article) {
    $articles[] = [
      '#type' => 'html_tag',
      '#html_tag' => 'h2',
      '#value' => $article->title->value,
      // The other methods add cache tags automatically, but we need to add
      // cache tags manually here since we're building the array from scratch.
      '#cache' => [
        'tags' => $article->getCacheTags(),
      ],
    ];
  }

  return $articles;
}

Each of these examples returns an $articles array of renderable contents suitable as a return value from your myPage() method.

| improve this answer | |
  • Can i render the body of the article also with the title in the third example? – David montera Jun 29 at 1:13
  • #value' => $article->body->value, i can render it but i need to render both of them not one , – David montera Jun 29 at 1:25
  • Yes, render arrays can be nested so for each article you'd just have to add an array with two render arrays, one for title and one for body. If you're doing more than the one field you really should make a view mode and render it, or, at a minimum, create your own theme hook to render your content. You really don't want to build complex render arrays in PHP here, the UI will do it for you. There's a lot of information out there on each of those subjects. If you're having trouble with that stuff, please feel free to open a new question. – sonfd Jun 29 at 1:46
  • okey i will ask a question now about that issue – David montera Jun 29 at 3:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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