15

I'm trying to retrieve the current product's attributes in a block in Magento 2. I can get a product, like id 1:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager->create('\Magento\Catalog\Model\ProductRepository')->getById(1);

I don't know how to get the ID of the current product though. How do I do that?

  • u can call function getProduct() in Magento\Catalog\Block\Product\View – xanka Feb 17 '16 at 9:13
  • where are u want to get current product? – Amit Bera Feb 17 '16 at 9:27
  • I'm adding a module to show the product's specifications (attributes) in a tab on the product page. Problem solved via $block->getProduct() per answer from Rahil Patel. – Tim Trampedach Feb 17 '16 at 22:26
  • Please check below links mageplaza.com/how-get-current-product-category-magento-2.html You can get current product using registry. Thanks !! – Mukesh Prajapati Nov 30 '17 at 10:46
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review – Jai Sep 13 '18 at 10:22
11

In order to get the current product, one of the recommended ways is:

  1. Extend or use block class: Magento\Catalog\Block\Product\View\AbstractView.
  2. Get product using: $block->getProduct() in your phtml file.
  • 6
    Or you can try this $this->_coreRegistry->registry('product'); as well!! – Rahil Patel Feb 17 '16 at 9:15
  • #2 works very well. Not sure why I couldn't figure that out myself. Thanks for your help! – Tim Trampedach Feb 17 '16 at 22:25
  • Could you help as to i get the error in load() to get the product id $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $currentproduct = $objectManager->create('Vendor\Module\Model\Queue')->load($productId); – Sushivam Aug 22 '16 at 7:13
  • @SachinS Please provide more details so that i can assist you. – Rahil Patel Aug 25 '16 at 12:55
  • 2
    AbstractView starts with capital A Magento\Catalog\Block\Product\View\AbstractView – Patrick van Bergen Jan 11 '17 at 15:14
27

Although other answers are correct, they're not the recommended/proper solution either.

Using the ObjectManager is absolutely prohibited in Magento 2. So please don't rely on this solution, but use proper DI to achieve this instead. To learn how to use DI in Magento 2, see this resource: http://devdocs.magento.com/guides/v2.0/extension-dev-guide/depend-inj.html

Extending AbstractView is not necessary. If you look at the original function in the AbstractView, you can see Magento used the registry to fetch the product. You don't need to extend a specific class to do this, simply inject Magento\Framework\Registry into your constructor and request the "product" registry item.

Full code example:

<?php

// Example = Module namespace, Module = module name, rest of the namespace is just for example only, change this to whatever it is in your case.
namespace Example\Module\Block\Frontend\Catalog\Product\General;

use Magento\Catalog\Model\Product;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Registry;
use Magento\Framework\View\Element\Template;

class Information extends Template
{

    /**
     * @var Registry
     */
    protected $registry;

    /**
     * @var Product
     */
    private $product;

    public function __construct(Template\Context $context,
                                Registry $registry,
                                array $data)
    {
        $this->registry = $registry;

        parent::__construct($context, $data);
    }


    /**
     * @return Product
     */
    private function getProduct()
    {
        if (is_null($this->product)) {
            $this->product = $this->registry->registry('product');

            if (!$this->product->getId()) {
                throw new LocalizedException(__('Failed to initialize product'));
            }
        }

        return $this->product;
    }

    public function getProductName()
    {
        return $this->getProduct()->getName();
    }

}
  • welcome to Magento SE. If you have comments on other answers, please use the "add a comment" link to do so. Please write an answer that stands on it's own as much as possible and don't rely on other answers. Other answers might be deleted or might "disappear" to the lower regions of the page. – 7ochem Nov 28 '16 at 19:30
  • @7ochem apologies, it said I wasn't allowed to comment yet, that's why I did it like this, I'll use proper comments in the future. :) – Wesley Vestjens Dec 4 '16 at 9:31
  • I already have module and can you please guide how to use your function in my current module? AND i would say, you explanation is best one which i need to implement in my module. Thanks – Sharma Nov 7 '17 at 6:47
  • Hi Sharma, it's hard to say exactly without seeing the code, but the idea remains the same: in your constructor (the one with 2 underscores), add a new argument and inject Magento\Framework\Registry into your block. Then, use the registry to get the product like this: $this->product = $this->registry->registry('product'); – Wesley Vestjens Nov 8 '17 at 7:59
  • 1
    Registry is deprecated and the method of @rafael-corrêa-gomes has to be used instead. – Christophe Ferreboeuf Apr 26 at 7:56
5

If you are using Magento 2.1 or major, you can use this helper because the old method was deprecated.

...
use Magento\Catalog\Helper\Data;
...

public function __construct(
        Context $context,
        Data $helper,
        array $data = []
    ){
        $this->context = $context;
        $this->helper = $helper;
        $this->data = $data;
        parent::__construct($context, $data);
    }

...

public function getProduct(){
    if(is_null($this->_product)){
        $this->_product = $this->helper->getProduct();
    }
    return $this->_product;
}
0

@Wesley Vestjens solution worked for me as well. Just make sure to pay attention to the access modifier, as private might not be what you want if you are using getProduct() in your template. In the above example it works as getProductName() is the public method to use.

  • It's generally recommended not to give entire objects to a template, but instead pass the data that it requires and nothing more. That's why getProduct() is private and getProductName() is public. In the newer Magento versions (2.2 / 2.3 and on) these methods are also considered deprecated and View Models should be used instead. – Wesley Vestjens Mar 23 at 15:50

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.