In a custom module (sel), I have this code:

function sel_cron()
  $accountSwitcher = Drupal::service('account_switcher');
  $account = \Drupal\user\Entity\User::load(1);

  $query = \Drupal::entityQuery('service_category');
  $dLastExtractionDate = strftime("%Y-%m-%d", strtotime("- 1 week", strtotime(\Drupal::state()->get('sel.NextEmailForNewServices'))));
  $view = views_embed_view('sel_services', 'embed_2', $dLastExtractionDate);
  $view = \Drupal::service('renderer')->render($view);   <--------------------- problem here


The expected result of the view is a table but when the result is empty (because of the value of the contextual filter), an unfiltered text ("Nothing to display today. Too bad!") should be displayed instead.
But in this case, I get this error logged:

LogicException: Render context is empty, because render() was called outside of a renderRoot() or renderPlain() call. Use renderPlain()/renderRoot() or #lazy_builder/#pre_render instead. in Drupal\Core\Render\Renderer->doRender() (line 243 of /Users/efalzon/Sites/JdP8/web/core/lib/Drupal/Core/Render/Renderer.php).

How to fix that?

  • 1
    That's a cron job though - where are you expecting it to render?
    – Clive
    Commented Apr 28, 2020 at 12:11
  • The result of the view becomes the body of an email sent with \Drupal::service('plugin.manager.mail')->mail(some params);
    – gbmapo
    Commented Apr 28, 2020 at 12:17
  • 4
    Oh ok, in that case you want to use renderPlain, not render. See drupal.stackexchange.com/questions/292171/…
    – Clive
    Commented Apr 28, 2020 at 12:22

1 Answer 1

$view = \Drupal::service('renderer')->renderPlain($view);

instead of

$view = \Drupal::service('renderer')->render($view);

was the solution!
Thanks to @Clive

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.