Magento2 Module Adminhtml Grid – Fatal Error: Uncaught Error: Call to a Member Function setSortable() on Boolean

adminhtmlcustomgridmagento2module

I am getting below error while loading admin grid of my custom module.

Fatal error: Uncaught Error: Call to a member function setSortable() on boolean in D:\xampp\htdocs\magento2\vendor\magento\module-backend\Block\Widget\Grid.php:413 Stack trace: #0
D:\xampp\htdocs\magento2\vendor\magento\module-backend\Block\Widget\Grid.php(467): Magento\Backend\Block\Widget\Grid->_prepareGrid() #1 
D:\xampp\htdocs\magento2\vendor\magento\framework\View\Element\AbstractBlock.php(658): Magento\Backend\Block\Widget\Grid->_beforeToHtml() #2
D:\xampp\htdocs\magento2\vendor\magento\framework\View\Layout.php(542): Magento\Framework\View\Element\AbstractBlock->toHtml() #3` 
D:\xampp\htdocs\magento2\vendor\magento\framework\View\Layout.php(518): Magento\Framework\View\Layout->_renderBlock('adminhtml_prici...') #4 
D:\xampp\htdocs\magento2\var\generation\Magento\Framework\View\Layout\Interceptor.php(206): Magento\Framework\View\Layout->renderNonCachedElement('adminhtml_prici...') #5 
D:\xampp\htdocs\magento2\vendor\magento\framework\View\Layout.php(472): Mag in 
D:\xampp\htdocs\magento2\vendor\magento\module-backend\Block\Widget\Grid.php on line 413

Best Answer

It may be that your adminhtml layout file is missing the grid.columnSet block.

Without having your code, the most-likely issue is that you do not have your grid set up correctly. The reason that error would appear is this line:

$this->getColumnSet()->setSortable($this->getSortable());

$this->getColumnSet() must be returning a boolean (mostl likely false).

/**
 * Retrieve column set block
 *
 * @return \Magento\Backend\Block\Widget\Grid\ColumnSet
 */
public function getColumnSet()
{
    return $this->getChildBlock('grid.columnSet');
}

So, $this->getChildBlock('grid.columnSet'); must be returning the boolean, instead of \Magento\Backend\Block\Widget\Grid\ColumnSet. Let's dig in:

/**
 * Retrieve child block by name
 *
 * @param string $alias
 * @return \Magento\Framework\View\Element\AbstractBlock|bool
 */
public function getChildBlock($alias)
{
    $layout = $this->getLayout();
    if (!$layout) {
        return false;
    }
    $name = $layout->getChildName($this->getNameInLayout(), $alias);
    if ($name) {
        return $layout->getBlock($name);
    }
    return false;
}

It looks like there are a few different reasons why this may be happening:

  1. $this->getLayout() returns false. Most likely this is not the case.
  2. The $alias, whose value is 'grid.columnSet' block is not found in layout as a child of the current block.

Here is a redacted version of what this looks like in the Newsletter module.

vendor/magento/module-newsletter/view/adminhtml/layout/newsletter_subscriber_block.xml

<block class="Magento\Backend\Block\Widget\Grid\ColumnSet" name="adminhtml.newslettrer.subscriber.grid.columnSet" as="grid.columnSet">
    <arguments>
        <argument name="id" xsi:type="string">problemGrid</argument>
    </arguments>
    <block class="Magento\Backend\Block\Widget\Grid\Column" as="subscriber_id">
        <arguments>
            <argument name="header" xsi:type="string" translate="true">ID</argument>
            <argument name="index" xsi:type="string">subscriber_id</argument>
            <argument name="header_css_class" xsi:type="string">col-id</argument>
            <argument name="column_css_class" xsi:type="string">col-id</argument>
        </arguments>
    </block>
    <block class="Magento\Backend\Block\Widget\Grid\Column" as="email">
        <arguments>
            <argument name="header" xsi:type="string" translate="true">Email</argument>
            <argument name="index" xsi:type="string">subscriber_email</argument>
            <argument name="header_css_class" xsi:type="string">col-email</argument>
            <argument name="column_css_class" xsi:type="string">ccol-email</argument>
        </arguments>
    </block>

    <!-- snip -->

</block>
Related Topic