Magento 2 – Product Collection: Invalid Argument Supplied for foreach()

magento-2.1product

I get product collection using dependency injection rather than directly using object Manager, this is the way most people suggest, but when I visit the product collection template, it shows:

Error filtering template: Warning: Invalid argument supplied for foreach() in …/xxx.phtml

How to fix it?


The codes I used is most people suggest like below. I guess the codes could has some tiny mistake which I did not find.

In block:

<?php
namespace Vendor\HelloWorld\Block;
class HelloWorld extends \Magento\Framework\View\Element\Template
{    
    protected $_productCollectionFactory;

    public function __construct(
        \Magento\Backend\Block\Template\Context $context,        
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,        
        array $data = []
    )
    {    
        $this->_productCollectionFactory = $productCollectionFactory;    
        parent::__construct($context, $data);
    }

    public function getProductCollection()
    {
        $collection = $this->_productCollectionFactory->create();
        $collection->addAttributeToSelect('*');
        $collection->setPageSize(3); // fetching only 3 products
        return $collection;
    }
}
?>

In template (.phtml) file:

$productCollection = $block->getProductCollection();
foreach ($productCollection as $product) {
    print_r($product->getData());     
    echo "<br>";
}

Best Answer

Warning: Invalid argument supplied for foreach()

This error means your input data is not an array or be null. And in your case, it's obvious that your input data is not an array. It's returning Magento\Catalog\Model\ResourceModel\Product\Collection instance.

To fix this problem, you can simply add getData() in return $collection. So your getProductCollection() will look like.

public function getProductCollection()
{
    $collection = $this->_productCollectionFactory->create();
    $collection->addAttributeToSelect('*');
    $collection->setPageSize(3); // fetching only 3 products
    return $collection->getData();
}

Hope it helps.