2

I am trying to show the configurable product options on the category page, for our store set up these are configurable products with simple products as options - not as custom attributes.

I want to pass the current product ID into the getJsonConfig() so that it can work through the loop, and also so I can call getAllowAttributes() so I can then link into the dropdown in a phtml file being called.

The problem is getTypeInstance() returns null even when the product has a set of configurable options. Also for some reason my ::__construct is required to be very explicit, Magento throws an exception until everything has been called in it even though I copied the construct from the \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable.php file.

I want to call $productRepository so that I can get the current product by ID from the foreach loop on the category.

Fatal error: Call to a member function getTypeInstance() on null in /home/agstage/public_html/vendor/magento/module-configurable-product/Block/Product/View/Type/Configurable.php on line 136

<?php

namespace Vendor\Module\Block\Category\View\Type;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\ConfigurableProduct\Model\ConfigurableAttributeData;    
use Magento\Customer\Helper\Session\CurrentCustomer;
use Magento\Framework\Pricing\PriceCurrencyInterface;

class Configurables extends \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable
{

protected $productRepository;

/**
 * Catalog product
 *
 * @var \Magento\Catalog\Helper\Product
 */
protected $catalogProduct = null;

/**
 * Prices
 *
 * @var array
 */
protected $_prices = [];

/**
 * @var \Magento\Framework\Json\EncoderInterface
 */
protected $jsonEncoder;

/**
 * @var \Magento\ConfigurableProduct\Helper\Data $imageHelper
 */
protected $helper;

/**
 * @var PriceCurrencyInterface
 */
protected $priceCurrency;

/**
 * @var ConfigurableAttributeData
 */
protected $configurableAttributeData;

public function __construct(
    \Magento\Catalog\Block\Product\Context $context,
    \Magento\Framework\Stdlib\ArrayUtils $arrayUtils,
    \Magento\Framework\Json\EncoderInterface $jsonEncoder,
    \Magento\ConfigurableProduct\Helper\Data $helper,
    \Magento\Catalog\Helper\Product $catalogProduct,
    CurrentCustomer $currentCustomer,
    PriceCurrencyInterface $priceCurrency,
    ConfigurableAttributeData $configurableAttributeData,
    ProductRepositoryInterface $productRepository,
    array $data = []
) {
    $this->priceCurrency = $priceCurrency;
    $this->helper = $helper;
    $this->jsonEncoder = $jsonEncoder;
    $this->catalogProduct = $catalogProduct;
    $this->currentCustomer = $currentCustomer;
    $this->configurableAttributeData = $configurableAttributeData;
    $this->productRepository = $productRepository;
    parent::__construct(
        $context,
        $arrayUtils,
        $jsonEncoder,
        $helper,
        $catalogProduct,
        $currentCustomer,
        $priceCurrency,
        $configurableAttributeData,
        $data
    );
}

public function getConfigProduct($product_id)
{

    return $product = $this->productRepository->getById($product_id);
}

/**
 * Composes configuration for js
 *
 * @param $product_id
 * @return mixed
 */
public function getJsonConfigOptions($product_id)
{

    $store = $this->getCurrentStore();
    $currentProduct = $this->getConfigProduct($product_id);

    if($currentProduct->getTypeId() == 'configurable') {

        $regularPrice = $currentProduct->getPriceInfo()->getPrice('regular_price');
        $finalPrice = $currentProduct->getPriceInfo()->getPrice('final_price');

        $options = $this->helper->getOptions($currentProduct, $this->getAllowProducts());
        $attributesData = $this->configurableAttributeData->getAttributesData($currentProduct, $options);

        $config = [
            'attributes' => $attributesData['attributes'],
            'template' => str_replace('%s', '<%- data.price %>', $store->getCurrentCurrency()->getOutputFormat()),
            'optionPrices' => $this->getOptionPrices(),
            'prices' => [
                'oldPrice' => [
                    'amount' => $this->_registerJsPrice($regularPrice->getAmount()->getValue()),
                ],
                'basePrice' => [
                    'amount' => $this->_registerJsPrice(
                        $finalPrice->getAmount()->getBaseAmount()
                    ),
                ],
                'finalPrice' => [
                    'amount' => $this->_registerJsPrice($finalPrice->getAmount()->getValue()),
                ],
            ],
            'productId' => $currentProduct->getId(),
            'chooseText' => __('Choose an Option...'),
            'images' => isset($options['images']) ? $options['images'] : [],
            'index' => isset($options['index']) ? $options['index'] : [],
        ];

        if ($currentProduct->hasPreconfiguredValues() && !empty($attributesData['defaultValues'])) {
            $config['defaultValues'] = $attributesData['defaultValues'];
        }

        $config = array_merge($config, array());

        return $this->jsonEncoder->encode($config);
    } else {
        return false;
    }

}

}

How am I able to amend the above so that I can retrieve the configurable attributes json on the category page?

  • Have you got your answer. I am also working on the category view page as like you. But didn't get a solution yet. If you have done that please share your solution. It will help me too. Thank you so much! – Ranjod8192 Nov 21 '18 at 6:25
  • This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. You can also add a bounty to draw more attention to this question once you have enough reputation. - From Review – Rama Chandran M Nov 21 '18 at 6:48
  • Yes we did but in a complete different route in a custom module. The solution doesn't fit the question unfortunately. – Aravona Nov 21 '18 at 11:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.