Magento 2.1 – Fixing Json Return from Controller: Recoverable Error

controllersjsonmagento-2.1

How can i pass json from controller.

<?php

namespace Swarming\FindProdFast\Controller\Index;

use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ResponseInterface;

class FilterOptions extends \Magento\Framework\App\Action\Action
{
    protected $_altAttributeCode = 'depth_feet';
    protected $_attributeCode = 'depth';
    protected $customerSession;
    protected $_productCollectionFactory;
    protected $_categoryCollectionFactory;
    protected  $_resource;
    protected $resultJsonFactory;

    public function __construct(
        \Magento\Customer\Model\Session $customerSession, 
        \Magento\Framework\App\Request\Http $request,  
        Context $context,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,   
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
        \Magento\Framework\App\ResourceConnection $resource,
        \Magento\Eav\Model\Entity\Attribute $entityAttribute,
        \Magento\Eav\Model\Config $eavConfig
    ){
        $this->customerSession = $customerSession;
        $this->_categoryFactory = $categoryFactory;
        $this->categoryCollectionFactory = $categoryCollectionFactory;
        $this->_productCollectionFactory = $productCollectionFactory;    
        $this->request = $request;
        $this->_entityAttribute = $entityAttribute;
        $this->_resource = $resource;
        $this->eavConfig = $eavConfig;
        parent::__construct($context);
        $this->resultJsonFactory = $resultJsonFactory;
    }

    public function execute()
    {   
        $this->updateSessionValues();
        $productCollection = $this->initProductCollection();
        $sql = $productCollection->getSelect()->__toString();
        $html = $this->getAttributeHtml($productCollection);
        $this->getResponse()->setBody($html);
    }

    protected function updateSessionValues()
    {
        //Get the customer session
        $customerSession = $this->customerSession;
        //Get the name of the select that was selected
        $requestedAttribute = $this->request->getPost('name');
        //Get the value of the attribute that was selected
        $selectedValue = $this->request->getPost('value');
        //Hold the "next" value
        $nextValue = $this->request->getPost('next');
        //I'm keeping track of all the types
        $usedSessionKeys = $customerSession->getData('used_session_keys');
        if (empty($usedSessionKeys)) {
            $usedSessionKeys = array();
        }
        //Get any values that had to be cleared
        $cleared = json_decode($this->request->getPost('cleared'));
        if (isset($cleared) && count($cleared)) {
            foreach ($cleared as $clear) {
                $customerSession->unsetData($clear);
                unset($usedSessionKeys[$clear]);
            }
            $customerSession->setData('used_session_keys', $usedSessionKeys);
        }
        $usedSessionKeys[$requestedAttribute] = $selectedValue;
        $customerSession->setData('used_session_keys', $usedSessionKeys);
        $customerSession->setData($requestedAttribute, $selectedValue);
        $customerSession->setData('next', $nextValue);
        $customerSession->setData('current_attribute', $requestedAttribute);

    }

    protected function initProductCollection()
    {
        /** @var Mage_Catalog_Model_Resource_Product_Collection $collection */
        $collection =  $this->getProductCollection();

        $customerSession =  $this->customerSession;
        $usedSessionKeys = $customerSession->getUsedSessionKeys();

        foreach ( $usedSessionKeys as $key => $value) {
            if ($key == 'product-category') {
                $collection->addCategoriesFilter(['eq' => $value]);

            } else {
                $attributeCode = $this->isAltAttributeRequired($key) ? $this->getAltAttributeCode() : $key;
                $collection = $this->joinAttributeOptions($collection, $attributeCode, $value);
            }
        }

        $next = $customerSession->getData('next');
        if (!isset($usedSessionKeys[$next]) && !empty($next)) {
            $attributeCode = $this->isAltAttributeRequired($next) ? $this->getAltAttributeCode() : $next;
            $collection = $this->joinAttributeOptions($collection, $attributeCode);
        }
        return $collection;
    }

    protected function getProductCollection()
    {
        $collection = $this->_productCollectionFactory->create();
        $collection->addAttributeToSelect('*');
        return $collection;
    }

    /**
     * @param Mage_Catalog_Model_Resource_Product_Collection $collection
     * @return string
     */
    protected function getAttributeHtml($collection)
    {
        $next = $this->customerSession->getData('next');
        $response = array();
        $dataHelper = \Magento\Framework\App\ObjectManager::getInstance()->get("\Swarming\Utilities\Helper\Data");
        if (!empty($next)) {
            $attributeCode = $this->isAltAttributeRequired($next) ? $this->getAltAttributeCode() : $next;
            $attribute = $this->eavConfig->getAttribute('catalog_product', $attributeCode);
            $values = $this->getAttributeValues($collection, $attributeCode);
            $html = '<option disabled="disabled" selected="selected">Select ' . $attribute->getFrontendLabel() . '</option>';
            $selected = count($values) == 1 ? 'selected="selected"' : '';
            $count = count($values);
            foreach ($values as $value) {
                $option = '<option value="' . $value['option_id'] . '"' . $selected . '>' . $dataHelper->convertFraction($value['value']) .'</option>';
                $html .= $option;
            }
            $response['html'] = $html;
            $response['count'] = $count;
        }else{
            $response['html'] = "";
        }
         $result = $this->resultJsonFactory->create();
         return $result->setData($response);
    }

    /**
     * @param Mage_Catalog_Model_Resource_Product_Collection $collection
     * @param string $attributeCode
     * @param $value
     * @return Mage_Catalog_Model_Resource_Product_Collection
     * @throws Mage_Core_Exception
     */
    protected function joinAttributeOptions($collection, $attributeCode, $value = null)
    {
        /** @var Mage_Core_Model_Resource $resource */
        $resource = $this->_resource->getConnection(\Magento\Framework\App\ResourceConnection::DEFAULT_CONNECTION);
        //Get some table names to use in joins
        $catalogProductInt = $resource->getTableName('catalog_product_entity_int');
        $eavAttributeOption = $resource->getTableName('eav_attribute_option');
        $eavAttributeOptionValue = $resource->getTableName('eav_attribute_option_value');


        $attribute = $this->eavConfig->getAttribute('catalog_product', $attributeCode);
        $optionValue   = $attributeCode . '_value';
        $option = $attributeCode . '_option';
        $collection->getSelect()
            ->join(array($attributeCode => $catalogProductInt), "$attributeCode.row_id = e.entity_id and $attributeCode.attribute_id = " . $attribute->getAttributeId());
        $collection->getSelect()
            ->join(array($optionValue => $eavAttributeOptionValue), "$attributeCode.value = $optionValue.option_id");
        $collection->getSelect()
            ->joinLeft(array($option => $eavAttributeOption), "$optionValue.option_id = $option.option_id");
        if ($value) {
            $collection->getSelect()->where("$optionValue.option_id = ?", $value);
        }

        return $collection;
    }

    /**
     * @param Mage_Catalog_Model_Resource_Product_Collection $collection
     * @param string $attributeCode
     * @return array
     */
    protected function getAttributeValues($collection, $attributeCode)
    {
        $collection->getSelect()->reset(\Zend_Db_Select::COLUMNS);
        $collection->getSelect()->columns(array(sprintf('%s_value.value', $attributeCode), sprintf('%s_value.option_id', $attributeCode)));
        $collection->getSelect()->group(sprintf('%s_value.value', $attributeCode));
        $collection->getSelect()->order(sprintf('%s_option.sort_order', $attributeCode));

        $finalSql = $collection->getSelect()->__toString();

        $readConnection = $this->_resource->getConnection(\Magento\Framework\App\ResourceConnection::DEFAULT_CONNECTION);
        $attributeValues = $readConnection->fetchAll($collection->getSelect());

        return $attributeValues;
    }

    protected function isAltAttributeRequired($attributeCode = null)
    {
        $customerSession = $this->customerSession;
        $usedSessionKeys = $customerSession->getUsedSessionKeys();
        if ($usedSessionKeys && array_key_exists('product-category', $usedSessionKeys)) {
            $category = $usedSessionKeys['product-category'];
        } else {
            return false;
        }

        $parentData = $this->_categoryFactory->create()->getCollection()->addAttributeToSelect('*')->addAttributeToFilter('name','Thermal Ribbons');
        $parentData = $parentData->getData();
        $problemCategoryParent = $this->_categoryFactory->create()->load($parentData[0]['entity_id']);

        $problemCategories = explode(',', $problemCategoryParent->getChildren());
        array_unshift($problemCategories, $problemCategoryParent->getId());
        if ($attributeCode) {
            return array_search($category, $problemCategories) !== false && $attributeCode == $this->getAttributeCode() ? true : false;
        } else {
            return array_search($category, $problemCategories) !== false ? true : false;
        }

    }

    protected function getAltAttributeCode()
    {
        return $this->_altAttributeCode;
    }

    protected function getAttributeCode()
    {
        return $this->_attributeCode;
    }
}

When i am trying above code i got error :

a:4:{i:0;s:238:"Recoverable Error: Object of class Magento\Framework\Controller\Result\Json\Interceptor could not be converted to string in

Best Answer

use Magento\Framework\Controller\Result\JsonFactory;


protected $resultJsonFactory;


public function __construct(
    ...
    JsonFactory $resultJsonFactory,
    ....
) {
    ....
    $this->resultJsonFactory = $resultJsonFactory;  
    ....
}

So now prepare your JSON content and return it

$result = $this->resultJsonFactory->create();
$yourData['value'] = 'test';
return $result->setData($yourData);

EDIT


 public function execute()
    {   
        $this->updateSessionValues();
        $productCollection = $this->initProductCollection();
        $sql = $productCollection->getSelect()->__toString();
        $html = $this->getAttributeHtml($productCollection);
        $result = $this->resultJsonFactory->create(); // change here
        return $result->setData($html);        // change here
    }

    ...........................

    /**
     * @param Mage_Catalog_Model_Resource_Product_Collection $collection
     * @return string
     */
    protected function getAttributeHtml($collection)
    {
        $next = $this->customerSession->getData('next');
        $response = array();
        $dataHelper = \Magento\Framework\App\ObjectManager::getInstance()->get("\Swarming\Utilities\Helper\Data");
        if (!empty($next)) {
            $attributeCode = $this->isAltAttributeRequired($next) ? $this->getAltAttributeCode() : $next;
            $attribute = $this->eavConfig->getAttribute('catalog_product', $attributeCode);
            $values = $this->getAttributeValues($collection, $attributeCode);
            $html = '<option disabled="disabled" selected="selected">Select ' . $attribute->getFrontendLabel() . '</option>';
            $selected = count($values) == 1 ? 'selected="selected"' : '';
            $count = count($values);
            foreach ($values as $value) {
                $option = '<option value="' . $value['option_id'] . '"' . $selected . '>' . $dataHelper->convertFraction($value['value']) .'</option>';
                $html .= $option;
            }
            $response['html'] = $html;
            $response['count'] = $count;
        }else{
            $response['html'] = "";
        }
        return $response; // change here          
    }
Related Topic