I want to get product collection by category id on phtml file. For that I used below code but it's not working.

$collection = $this->productFactory->create()
->addCategoriesFilter(['eq' => 2]);

I also tried this link but when I use addCategoryFilter(\Magento\Catalog\Model\Category $category) in my phtml file it shows me error that unexpected $category on line no. xx

May I need to add anything to get product collection by category id? I am using addCategoriesFilter to get collection by category id. Is it right or I am doing something wrong?


2 Answers 2


You can add this in the Block, and call the function getProductCollection() in phtml,

protected $_productCollectionFactory;
protected $_categoryFactory;

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

public function getProductCollection()
    $categoryId = 'yourcategoryid';
    $category = $this->_categoryFactory->create()->load($categoryId);
    $collection = $this->_productCollectionFactory->create();
    $collection->addAttributeToFilter('visibility', \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH);
    return $collection;
  • I don't want to change code in core magento block file so is there any way to get product collection by category id on phtml page directly?
    – Dhaval
    Commented Jul 11, 2016 at 7:15
  • basically I have change category page. So now category page showing sub-category and I want to show one product for that category on category page. you helped me to get sub-category on category page now I want to showing one product of current category with sub category. How can I get it?
    – Dhaval
    Commented Jul 11, 2016 at 7:17
  • 4
    This is the correct answer. You should not load models or collections in template files. You need to override or change the block. Or create a new one.
    – Marius
    Commented Jul 11, 2016 at 7:18
  • 1
    yes you don't need to change core code just create your own block and you can call your phtml file to get collection based on filter.
    – Rushvi
    Commented Jul 11, 2016 at 7:18
  • @RJ07 can you tell me which block file is responsible for magento_catalog/templates/category/products.phtml file so I will override this block and can add getProductCollection function.
    – Dhaval
    Commented Jul 11, 2016 at 7:24

you can simply call block and get product collection using below code,

Inside BLock file,

namespace Company\Categories\Block;

class Categoryproduct extends \Magento\Framework\View\Element\Template
     protected $categoryFactory;

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,        
        \Magento\Catalog\Model\CategoryFactory $categoryFactory
    ) {
        $this->categoryFactory = $categoryFactory;

    public function getCategoryProduct($categoryId)
        $category = $this->categoryFactory->create()->load($categoryId)->getProductCollection()->addAttributeToSelect('*');
        return $category;

call function in your .phtml file,

$categoryId = 5;
$getProudctcollection = $block->getCategoryProduct($categoryId);

<ul class="category-products">  
                                foreach ($getProudctcollection as $product) : ?>
                                    <li class="level0-child">
                                        <a href="<?php echo $product->getProductUrl(); ?>">
                                            <?php echo $product->getName();?>
                        <?php   endforeach;?>
  • how to filter collection with Instock items? Commented Dec 26, 2018 at 6:28

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