30

I'm trying to grab a product attribute in the cart template. But I just does not work! The attribute is set to Visible on Catalog Pages on Storefront = yes and Used in Product Listing = yes

I use a custom module to override the following template:

/vendor/magento/module-checkout/view/frontend/templates/cart/item/default.phtml

I have the product:

$_item = $block->getItem();
$product = $_item->getProduct();

Normally I would expect a custom attribute (of type text-area in this case) with an attribute code of 'sample_attr' to be available with one of these:

$product->getData('sample_attr');

or

$product->getSampleAttr();

Some attributes are available using this (sku, weight, price ..), but for a custom attribute neither works. The included helper (\Magento\Msrp\Helper\Data) also has no attribute method.

I can get all attribute codes using:

   $attributes = $product->getAttributes();
   foreach($attributes as $a)
   {
     var_dump($a->getName());
   }

I've also tried:

    $attribute = $product->getResource()->getAttribute('sample_attr');
    var_dump($attribute->getFrontend()->getValue($product));

but this returns null.

So how do I get the value of the attribute?

I've tried these: Get specific attribute for each product on catalog page

Output custom text attribute in catalog list.phtml (Magento 2)

5 Answers 5

81

There is no necessity to change any PHP code for doing this.

You just need to create {MODULE_NAME}/etc/catalog_attributes.xml with such content:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/catalog_attributes.xsd">
    <group name="quote_item">
        <attribute name="sample_attr"/>
    </group>
</config>
8
  • Interesting. I hadn't thought of that. I'll give that a try later on.
    – tecjam
    Commented Sep 21, 2016 at 8:53
  • You're welcome :)
    – Igor S
    Commented Feb 3, 2017 at 15:18
  • 2
    Fantastic! Works for me. It did seem like I had to run magento setup:di:compile to get this to work, but that makes sense. You are changing the dependency tree here.
    – psyklopz
    Commented May 23, 2017 at 19:34
  • This should be the accepted answer IMHO. The other answers suggest loading the product model for each cart item which is not a good idea for performance reasons, especially when the users carts are large. Commented Oct 27, 2017 at 3:31
  • i have create a module tenx/checkoutex under etc i have placed above code but its not working can you help me Commented Nov 30, 2017 at 12:42
8

So I found a way to get the information I was after. I have to load the complete product from the ProductRepository! Note that if you try and load it from \Magento\Catalog\Model\Product it will behave like a singleton, always giving you the same product in for each loops.

I used my modules helper class as it defines the following method to load the product from the productId:

public function __construct(
  \Magento\Framework\App\Helper\Context $context,
  \Magento\Catalog\Model\ProductRepository $productRepo
) {
  $this->_productRepo = $productRepo;
  parent::__construct($context);
  }


/**
 * Load product from productId
 *
 * @param $id
 * @return $this
 */
public function getProductById($id)
{
    return $this->_productRepo
        ->getById($id);
}

I included the helper in the template:

$customHelper = $this->helper('MyCompany\MyModule\Helper\Data');

I load the full product:

$custProd = $customHelper->getProductById($product->getId());

And now I can use:

$custProd->getSampleAttr();

and

$custProd->getData('sample_attr');

to get the data.

2

For those landed here looking for a simple solution, that's how it worked out for me

I added to my default.phtml (in module-checkout/view/frontend/templates/cart/item) this:

<?php
    $product_id = $product->getId();
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $customProduct = $objectManager->get('Magento\Catalog\Model\Product')->load($product_id);
 ?>

then you can call $customProduct->getData('your_attribute'); as always

5
  • 3
    In the template, Magento discourages us to use ObjectManager directly. We should add in the block. Commented Aug 9, 2016 at 15:04
  • 3
    You should not use directly the ObjectManager not in the template, nor in the block.
    – ocornu
    Commented Jun 15, 2017 at 21:02
  • 2
    If you simply don't care how, this 100% works.
    – A. Lal
    Commented Dec 10, 2019 at 16:28
  • 1
    I would not recommend using this in production, as it loads the whole product, but you can also do: $product = $product->load($product->getId(). Afterwards, $product->getData() will have all the product data available.
    – Louis B.
    Commented Nov 17, 2020 at 7:23
  • $product = $product->load($product->getId() , $product->getData('sample_attr') it will work ?
    – John
    Commented Jan 11, 2021 at 9:04
1

With correct admin settings, custom attributes are loaded in the product object in Checkout page if the source model in the eav_attribute sql table is set to NULL. So you are able to access directly with $product->getSampleAttr() on the Checkout Page.

But if the attribute has a source model as Magento\Eav\Model\Entity\Attribute\Source\Table, you must load the product from the repository.

Create a new helper and add the product repository in the constructor is still working on 2.2.6 (as the tecjam's solution)

Please note issue is the same if you try to override the item renderer (called in the Checkout Page) and add the product repository here.

enter image description here

0

Custom attributes are not included in the product object found in Quote/Cart,so therefore you cant get it through the getData('custom_attribute') function. what you need to do is get the Id of the product returned from the Quote product object and load the product using the product repository, once you have loaded the product through repository then you can get all the data including the custom attributes assigned to it, later you can use the getData('custom_attribute') funciton to get it.

Hope it makes sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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