0

I'm trying to display upsell products on the view page. For that, I created my own custom block for the template with following code:

<?php

namespace YS\India\Block;

use Magento\Framework\App\ObjectManager;
use Magento\Catalog\Block\Product\AbstractProduct;

/**
 * Catalog product upsell items block
 *
 * @SuppressWarnings(PHPMD.LongVariable)
 */
class Upsell extends AbstractProduct
{
/**
 * @param \Magento\Catalog\Block\Product\Context $context
 * @param array $data
 */
public function __construct(
    \Magento\Catalog\Block\Product\Context $context
) {
    parent::__construct($context);
}

public function getUpSellProducts()
{
    $product = $this->_coreRegistry->registry('product');

    $upSellProductIds = $product->getUpSellProductIds();

    if(isset($upSellProductIds)){

        $products = array();
        $objectManager = ObjectManager::getInstance();

        foreach($upSellProductIds as $productId) {
            $product = $objectManager->get('Magento\Catalog\Model\Product')->load($productId);

            $products[] = $product;
        }

        return $products;
    }

    return null;
}
}

What's going with above code is this:

The following line is working fine and giving me upsell ids.

$upSellProductIds = $product->getUpSellProductIds();

The problem is after executing the loop:

foreach($upSellProductIds as $productId) {
    ....
}

the products array has same product although productId is different.

What I am missing here?

1

The main problem with your code is that you are using ObjectManager::get().
This will always return the same instance of the class you pass as parameter. It acts similar to Mage::getSingleton() in magento 1.
For a quick fix use $objectManager->create('Magento\Catalog\Model\Product').
But this is not the proper way to do it. You should use the object manager only in factories, and even there you should inject it in the constructor. You should not retrieve the instance like you do ObjectManager::getInstance();.

You should use the product factory instead.
Something like this:

<?php

namespace YS\India\Block;

use Magento\Framework\App\ObjectManager;
use Magento\Catalog\Block\Product\AbstractProduct;
use Magento\Catalog\Model\ProductFactory;

class Upsell extends AbstractProduct
{
    protected $productFactory;
    public function __construct(
        \Magento\Catalog\Block\Product\Context $context,
        ProductFactory $productFactory
    ) {
        $this->productFactory = $productFactory;
        parent::__construct($context);
    }

    public function getUpSellProducts()
    {
        $product = $this->_coreRegistry->registry('product');

        $upSellProductIds = $product->getUpSellProductIds();

        if(isset($upSellProductIds)){

            $products = array();

            foreach($upSellProductIds as $productId) {
                $product = $this->productFactory->create()->load($productId);
                $products[] = $product;
            }

            return $products;
        }

        return null;
    }
}
  • Thanks Marius for the quick answer. I tried productFactory but I'm getting following error: Argument 2 passed to YS\India\Block\Upsell::__construct() must be an instance of Magento\Catalog\Model\ProductRepository, instance of Magento\Checkout\Model\ResourceModel\Cart given – Ashutosh Pandey Jan 14 '16 at 9:19
  • clear contents of var/generation – Marius Jan 14 '16 at 9:21
1

Use Create instead of Get in foreach loop.

$product = $objectManager->create('Magento\Catalog\Model\Product')->load($productId);

This might help!!

0

With the help of Marius's answer, I was able to solve this with following code:

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

namespace YS\India\Block;

use Magento\Catalog\Model\ProductFactory;
use Magento\Catalog\Block\Product\AbstractProduct;
use Magento\Framework\View\Element\Template;
/**
 * Catalog product upsell items block
 *
 * @SuppressWarnings(PHPMD.LongVariable)
 */
class Upsell extends Template
{
protected $productFactory;

protected  $_coreRegistry;
/**
 * @param \Magento\Catalog\Block\Product\Context $context
 * @param array $data
 */
public function __construct(
    \Magento\Catalog\Block\Product\Context $context,
    ProductFactory $productFactory
) {
    $this->productFactory = $productFactory;
    $this->_coreRegistry = $context->getRegistry();

    parent::__construct($context);
}

public function getUpSellProducts()
{
    $product = $this->_coreRegistry->registry('product');

    $upSellProductIds = $product->getUpSellProductIds();

    if(isset($upSellProductIds)){

        $products = array();

        foreach($upSellProductIds as $productId) {
            $product = $this->productFactory->create()->load($productId);

            $products[] = $product;
        }

        return $products;
    }

    return null;
}
}

Your Answer

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

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