We are trying to get product collection by category id.

Block:

protected $_categoryFactory;

public function __construct(
    \Magento\Backend\Block\Template\Context $context,       
    \Magento\Catalog\Model\CategoryFactory $categoryFactory,
    array $data = []
)
{   
    $this->_categoryFactory = $categoryFactory;
    parent::__construct($context, $data);
}

public function getCategory($categoryId) 
{
    $category = $this->_categoryFactory->create();
    $category->load($categoryId);
    return $category;
}

public function getCategoryProducts($categoryId) 
{
    $products = $this->getCategory($categoryId)->getProductCollection();
    $products->addAttributeToSelect('*');
    return $products;
}  

and in html:

$categoryId = 6; // fetching products in category id 6
$categoryProducts = $block->getCategoryProducts($categoryId);
foreach ($categoryProducts as $product) {
    echo $product->getName() . ' - ' . $product->getProductUrl() . '<br />';
}

it works fine only if $categoryId = the highest level in the category tree. But if I change $categoryId to 2 (or 3... or etc but not last in category tree) it doesn't work.

How can I get it work?

  • $categoryId = 2 means it is root category. so it will not work for it. – Suresh Chikani Apr 14 '16 at 13:10
  • or 3... or etc but not last in category tree. it's not working. – PolyakovAO Apr 14 '16 at 14:53
  • are the products directly assigned to the categories? I'm asking because categories have the is_anchor switch which shows all products of all child categories on the category page, but I'm pretty sure those products are not assigned directly to the category. So lodaing the products of a category with the is anchor switch active will still only load the products which are directly assigned to the category while the category page will still render all products of all child categories – David Verholen Apr 14 '16 at 18:40

I did this task in this way: In block:

protected $_objectManager = null;
protected $_categoryFactory;
protected $_category;
protected $_productCollectionFactory;

public function __construct(
    \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Framework\ObjectManagerInterface $objectManager,
    \Magento\Catalog\Model\CategoryFactory $categoryFactory
) {
    $this->_productCollectionFactory = $productCollectionFactory;
    $this->_objectManager = $objectManager;
    $this->_categoryFactory = $categoryFactory;
    parent::__construct($context);
}


public function getCurrentCategory()
{
    $category = $this->_objectManager->get('Magento\Framework\Registry')->registry('current_category');
    return $category;
}

/**
 * Get category object
 *
 * @return \Magento\Catalog\Model\Category
 */
public function getCategory($categoryId)
{
    $this->_category = $this->_categoryFactory->create();
    $this->_category->load($categoryId);
    return $this->_category;
}

/**
 * Get all children categories IDs
 *
 * @param boolean $asArray return result as array instead of comma-separated list of IDs
 * @return array|string
 */
public function getAllChildren($asArray = false, $categoryId = false)
{
    if ($this->_category) {
        return $this->_category->getAllChildren($asArray);
    } else {
        return $this->getCategory($categoryId)->getAllChildren($asArray);
    }
}

public function getProductCollection($category_id_array)
{
    $collection = $this->_productCollectionFactory->create();
    $collection->addAttributeToSelect('*');
    $collection->addCategoriesFilter(['in' => $category_id_array]);
    $collection->addAttributeToFilter('visibility', \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH);
    $collection->addAttributeToFilter('status',\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
    $collection->setPageSize(9); // fetching only 9 products
    return $collection;
}

In phtml:

<?php
    $category_id_array = $this->getAllChildren(true,$this->getCurrentCategory()->getEntity_id());
    foreach ($block->getProductCollection($category_id_array) as $product) {
        var_dump($product->getData());
    }
?>

and it works in any category.

You can try the following code to resolve your query:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); 
$cateinstance = $objectManager->create('Magento\Catalog\Model\CategoryFactory');
$cateid = '14';
$allcategoryproduct = $cateinstance->create()->load($cateid)->getProductCollection()->addAttributeToSelect('*');

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.