Fetch view results from mymodule_preprocess_page hook We have a View page that is coming from myview. Using the header setting in the view we have added @total results already, which displays in the views-view--myview--page-1.html.twig using the {{ header }} variable. 

We want to be able to fetch the view results within our mymodule_preprocess_page() hook. On the View page, we added facet blocks that will return a list of checkboxes (this is from the Article's category tag). 

Issue

When we modify the facet value to some value such as value1, the ksm($view-&gt;total_results) returns NULL value. 

Questions:


How would i fetch the results using mymodule_preprocess_page() hook?
Is there a way to do it without running a query within mymodule_preprocess_page() hook?


View Setup

Display: page

Format


unformatted list
rendered entity | "my_view_mode"


Filter criteria


published = true
content type = article


Header


Global: result summary (global: result summary)


Other
 - Machine name: page_1
 - Use Ajax = yes

What we tried:

function mymodule_preprocess_page($variables) {
  $view_id = \Drupal::routeMatch()-&gt;getParameter('view_id');
  $display_id = \Drupal::routeMatch()-&gt;getParameter('display_id');

  if($view_id == 'myviewId' &amp;&amp; $display_id = 'page_1') {
    // first check we are on view page.
    $view = \Drupal\views\Views::getView($view_id);
    ksm($view-&gt;total_results); // returns null. 
  }
}
The easiest way would be to execute the View again in the page preprocess hook.

If you want to avoid executing the View twice the task is getting a bit more tricky. This is because in D8 page elements are not necessarily rendered downstream in the order you expect. The element could have been cached in a previous request or in case the element doesn't qualify for caching it could have automatically been placeholdered and the page has been built without it, postponing the rendering until the cached page is finally delivered.

In Drupal 8 elements often need to send information upstream despite being cached or placeholdered, like cache tags or libraries. The mechanism for this is bubbleable metadata. You can use this for other things, too. See for example  Add an attribute to $variables from a Controller

In case of the views results you can try this:

/**
 * Implements hook_views_pre_render().
 */
function mymodule_views_pre_render($view) {
  if (isset($view) &amp;&amp; ($view-&gt;id() == 'my_view')) {
    $view-&gt;element['#attached']['placeholders']['&lt;div id="my-view-results"&gt;&lt;/div&gt;']['#markup'] =
      '&lt;div id="my-view-results"&gt;' . $view-&gt;total_rows . '&lt;/div&gt;';
  }
}


Place the empty div container somewhere on the page, for example in the body field of a custom block or directly in page.html.twig:

&lt;div id="my-view-results"&gt;&lt;/div&gt;


AJAX

When you enable AJAX the code above only works for the first page load. To update the results when the View gets refreshed via AJAX add your own command in a response event subscriber.

Getting the executed View then is straightforward, Views AJAX implementation keeps it in the response, so that you can use it when altering the response, see ViewAjaxResponse::getView.

/src/EventSubscriber/ViewAjaxResponseSubscriber.php

&lt;?php

namespace Drupal\mymodule\EventSubscriber;

use Drupal\views\Ajax\ViewAjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * Response subscriber to handle View AJAX responses.
 */
class ViewAjaxResponseSubscriber implements EventSubscriberInterface {

  /**
   * Adds an AJAX command to ViewAjaxResponse.
   */
  public function onResponse(FilterResponseEvent $event) {
    $response = $event-&gt;getResponse();
    if ($response instanceof ViewAjaxResponse) {
      $view = $response-&gt;getView();
      if (isset($view) &amp;&amp; ($view-&gt;id() == 'my_view')) {
        $response-&gt;addCommand(new HtmlCommand('#my-view-results', $view-&gt;total_rows));
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = ['onResponse'];
    return $events;
  }

}


mymodule.services.yml

services:
  mymodule.view_ajax_response_subscriber:
    class: Drupal\mymodule\EventSubscriber\ViewAjaxResponseSubscriber
    tags:
      - { name: event_subscriber }