Admin Grid – Modify/Preprocess Data Before Displaying in Magento 2

collection;gridmagento2uicomponent

I'd like to make some modifications before displaying it in admin grid. For now all what I want to do is just simply replace 0 and 1 in a column with Yes/No. There are a two ways that come to my mind.

First way is to modify the data before passing them to grid. (How? By an interceptor? Maybe there is there a way to modify the model collection?)

Second way is to make an own ui component that will handle that job.

What's the right way to do it?

Best Answer

As modyfing data for grid only should be, in my opinion, kept around the grid itself I've implemented some small column class modification by:

modyfing the layout column node:

<column name="required" class="\Vendor\ModuleName\Ui\Component\Listing\Column\Yesno">

and creating class \Vendor\ModuleName\Ui\Component\Listing\Column\Yesno:

<?php

namespace \Vendor\ModuleName\Ui\Component\Listing\Column;

use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Store\Model\StoreManagerInterface;

class Yesno extends \Magento\Ui\Component\Listing\Columns\Column
{
    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @param ContextInterface $context
     * @param UiComponentFactory $uiComponentFactory
     * @param StoreManagerInterface $storeManager
     * @param array $components
     * @param array $data
     */
    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        StoreManagerInterface $storeManager,
        array $components = [],
        array $data = []
    ) {
        $this->storeManager = $storeManager;
        parent::__construct($context, $uiComponentFactory, $components, $data);
    }

    /**
     * Prepare Data Source
     *
     * @param array $dataSource
     * @return array
     */
    public function prepareDataSource(array $dataSource)
    {
        if(isset($dataSource['data']['items'])) {
            foreach($dataSource['data']['items'] as & $item) {
                if($item) {
                    $item['required'] = ($item['required'] == 1 ? __('Yes') : new __('No'));
                }
            }
        }

        return $dataSource;
    }
}